{
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "",
    "title": "AIsa Ads",
    "version": "1",
    "x-aisa-capabilities": {
      "idempotency": "Idempotency-Key",
      "max_price": "X-AISA-Max-Price-USD",
      "quote": {
        "header": "X-AISA-Cost-Mode",
        "value": "quote"
      }
    },
    "x-aisa-configured-paths": [],
    "x-aisa-document": {
      "facts_hash": "fe60122939c67dc98a3a6ac6b97bd5c326b526105150c8959304dd2160d4dd09",
      "generator_version": "3",
      "protocol_version": "1",
      "schema_version": "1",
      "composer_version": "27",
      "response_pending": [],
      "document_hash": "sha256:ba353f59e89e1ebabe0e301d8ef57d3cbfa6bb406a8c591ee9c3833d64b60520"
    },
    "x-aisa-plans": {
      "builder": 1.0,
      "display_plan": "payg",
      "payg": 1.0,
      "similarweb_payg": 1.0,
      "team": 1.0,
      "version": "e70a0959cd1b93b84ae16dffd7a538273ddb9c1d46277b82823c37ff1b6bc0fb"
    },
    "x-aisa-provider": "aisa-ads",
    "x-aisa-catalogs": {
      "aisa-ads": {
        "title": "AIsa Ads",
        "description": "",
        "x-aisa-document": {
          "facts_hash": "fe60122939c67dc98a3a6ac6b97bd5c326b526105150c8959304dd2160d4dd09",
          "generator_version": "3",
          "protocol_version": "1",
          "schema_version": "1"
        },
        "x-aisa-plans": {
          "builder": 1.0,
          "display_plan": "payg",
          "payg": 1.0,
          "similarweb_payg": 1.0,
          "team": 1.0,
          "version": "e70a0959cd1b93b84ae16dffd7a538273ddb9c1d46277b82823c37ff1b6bc0fb"
        },
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "header": "X-AISA-Cost-Mode",
            "value": "quote"
          }
        }
      }
    }
  },
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "openapi": "3.1.0",
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "servers": [
    {
      "url": "https://api.aisa.one"
    }
  ],
  "paths": {
    "/apis/v1/ads": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists your ads with their performance over a date range, including ads created directly in each platform's ads manager. Returns a paginated list of ads with metrics computed over an optional date range. Use source=all to include externally-synced ads from platform ad managers. If no date range is provided, it defaults to the last 90 days. The date range is capped at 730 days max. ### History\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Page number (1-based)",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 500,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "source",
            "required": false,
            "schema": {
              "default": "all",
              "enum": [
                "aisa",
                "all"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "active",
                "paused",
                "pending_review",
                "rejected",
                "completed",
                "cancelled",
                "error"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "microsoft",
                "meta",
                "x"
              ],
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (e.g. act_123 for Meta). Mirrors the same filter on /apis/v1/ads/campaigns and /apis/v1/ads/tree.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only: Facebook Page ID. Returns only ads whose creative is backed by this Page (a Meta ad account serves ads for every Page in the Business Manager).",
            "in": "query",
            "name": "pageId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Platform campaign ID (filter ads within a campaign) Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "adSetId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta ad ID. Returns the ad with this platform-side ad ID. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "platformAdId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Facebook `{pageId}_{postId}` of the post the ad's engagement lives on (Meta `effective_object_story_id`).",
            "in": "query",
            "name": "effectiveObjectStoryId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Instagram media ID of the boosted post (Meta `effective_instagram_media_id`).",
            "in": "query",
            "name": "effectiveInstagramMediaId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start of metrics date range (YYYY-MM-DD). Defaults to 90 days ago.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End of metrics date range (YYYY-MM-DD). Defaults to today. Max 730-day range.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ads": {
                      "items": {
                        "properties": {
                          "_id": {
                            "type": "string"
                          },
                          "adSetName": {
                            "type": "string"
                          },
                          "adType": {
                            "enum": [
                              "boost",
                              "standalone"
                            ],
                            "type": "string"
                          },
                          "bidAmount": {
                            "description": "Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). Meta: `bid_amount` on the ad set (smallest-denomination int, decoded here).",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "bidStrategy": {
                            "anyOf": [
                              {
                                "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                                "enum": [
                                  "LOWEST_COST_WITHOUT_CAP",
                                  "LOWEST_COST_WITH_BID_CAP",
                                  "COST_CAP",
                                  "LOWEST_COST_WITH_MIN_ROAS"
                                ],
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Ad-set bid strategy (overrides campaign level on Meta). Populated for Meta and TikTok."
                          },
                          "budget": {
                            "properties": {
                              "amount": {
                                "type": "number"
                              },
                              "daily": {
                                "description": "LinkedIn and X only. The daily budget (LinkedIn: the parent campaign's `dailyBudget`; X: the line item's, or the campaign's when the line item has none).",
                                "type": "number"
                              },
                              "lifetime": {
                                "description": "LinkedIn and X only. The lifetime total (LinkedIn: the parent campaign's `totalBudget`; X: `total_budget_amount_local_micro`, for example the `lifetimeBudgetCap` of a boost), readable even when a daily budget is also set.",
                                "type": "number"
                              },
                              "pacing": {
                                "description": "LinkedIn only. The campaign's `pacingStrategy`: how fast LinkedIn may spend the budget. Typically LINEAR or ACCELERATED; the list is open.",
                                "type": "string"
                              },
                              "type": {
                                "enum": [
                                  "daily",
                                  "lifetime"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "campaignName": {
                            "type": "string"
                          },
                          "configuredStatus": {
                            "description": "The ad's own on/off switch as configured on the platform, independent of its parents. An ACTIVE ad under a paused ad set or campaign still reads ACTIVE here while `status` reads `paused`. Sources: Meta: `configured_status`.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "costType": {
                            "description": "LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn, refreshed on every sync rather than echoing what was passed on create. `null` for non-LinkedIn ads. `CPM`: cost per thousand impressions.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdAt": {
                            "format": "date-time",
                            "type": "string"
                          },
                          "creative": {
                            "description": "Platform-specific creative data. Fields vary by platform.",
                            "properties": {
                              "adFormat": {
                                "description": "LinkedIn only. The LinkedIn ad format, in LinkedIn's own vocabulary: STANDARD_UPDATE, SINGLE_VIDEO, CAROUSEL, NATIVE_DOCUMENT, EVENT, TEXT_AD, SPOTLIGHT, FOLLOW_COMPANY, JOBS, SPONSORED_INMAILS and others.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "assetGroup": {
                                "additionalProperties": true,
                                "description": "Google Performance Max creative assets. At least one description must be 60 characters or fewer. Texts within each list must be distinct.",
                                "type": "object"
                              },
                              "assetGroupResourceName": {
                                "description": "Google resource name of the created Performance Max asset group.",
                                "type": "string"
                              },
                              "assetResourceName": {
                                "description": "Google Display only. Resource name of the landscape marketing image asset (`creative.imageUrl`), for example customers/1234567890/assets/123.",
                                "type": "string"
                              },
                              "assets": {
                                "additionalProperties": true,
                                "description": "Google Display only. Native Google asset resource name of each image on the responsive display ad, keyed by Google's image role.",
                                "type": "object"
                              },
                              "bodies": {
                                "description": "Meta: every primary text variation of the creative (`asset_feed_spec.bodies`), the same shape as the `bodies` create input. Present only with 2 or more texts; a single text is `body`.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "body": {
                                "description": "Ad copy/text",
                                "type": "string"
                              },
                              "callToAction": {
                                "description": "Meta: the call to action type (`call_to_action.type`, or the first `asset_feed_spec.call_to_action_types` entry), e.g. LEARN_MORE or SIGN_UP.",
                                "type": "string"
                              },
                              "carouselCards": {
                                "description": "Meta only today. The carousel's cards in display order, one per Meta `link_data.child_attachments` entry, using the same field names as the `carouselCards` create input. Absent on non-carousel ads and other platforms.",
                                "items": {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "catalog": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "creativeFeatures": {
                                "additionalProperties": true,
                                "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                                "type": "object"
                              },
                              "creativeId": {
                                "description": "Meta ad creative id backing this ad, refreshed from Meta on every sync. Reusable via existingCreativeId on POST /apis/v1/ads/create, and readable raw through GET /apis/v1/ads/creatives/{creativeId}.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "description": {
                                "description": "Meta: the creative's description under the title (`link_data.description`, `video_data.link_description`, or the first `asset_feed_spec.descriptions` entry).",
                                "type": "string"
                              },
                              "descriptions": {
                                "description": "Google RSA: the description assets as objects (2 to 4). Meta: every description variation of the creative (`asset_feed_spec.descriptions`) as strings, the same shape as the `descriptions` create input.",
                                "items": {
                                  "oneOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "additionalProperties": true,
                                      "type": "object"
                                    }
                                  ]
                                },
                                "maxItems": 4,
                                "type": "array"
                              },
                              "effectiveInstagramMediaId": {
                                "description": "Meta `effective_instagram_media_id`, the Instagram media ID of the boosted post the ad's engagement lives on. Pass to GET /apis/v1/ads?effectiveInstagramMediaId= to map a Business-Manager-visible IG post back to this ad.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "effectiveObjectStoryId": {
                                "description": "Meta `effective_object_story_id`, the `{pageId}_{postId}` of the Facebook post the ad's engagement (comments) lives on.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "finalUrls": {
                                "description": "Google RSA only. Replaces final URLs. Omitted lists stay unchanged.",
                                "items": {
                                  "format": "uri",
                                  "type": "string"
                                },
                                "minItems": 1,
                                "type": "array"
                              },
                              "googleDescription": {
                                "description": "Google Ads description",
                                "type": "string"
                              },
                              "googleHeadline": {
                                "description": "Google Ads headline",
                                "type": "string"
                              },
                              "headline": {
                                "description": "Meta: the creative's title (`link_data.name`, `video_data.title`, or the first `asset_feed_spec.titles` entry). Absent when the creative has none.",
                                "type": "string"
                              },
                              "headlines": {
                                "description": "Google RSA: the headline assets as objects (3 to 15). Meta: every title variation of the creative (`asset_feed_spec.titles`) as strings, the same shape as the `headlines` create input.",
                                "items": {
                                  "oneOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "additionalProperties": true,
                                      "type": "object"
                                    }
                                  ]
                                },
                                "maxItems": 15,
                                "type": "array"
                              },
                              "imageHash": {
                                "description": "Meta: the ad image hash (`image_hash`), reusable as `imageHash` on POST /apis/v1/ads/create within the same ad account. `thumbnailUrl` and `mediaUrls` carry its stable full resolution permalink when Meta resolves it.",
                                "type": "string"
                              },
                              "imageUrl": {
                                "description": "Alternative image URL",
                                "type": "string"
                              },
                              "instagramPermalinkUrl": {
                                "description": "Meta `instagram_permalink_url`, the public Instagram post URL of the boosted media.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "instagramUserId": {
                                "description": "Meta `instagram_user_id`, the Instagram-scoped business ID that owns the boosted media.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "instagramVideoFallback": {
                                "additionalProperties": true,
                                "description": "Meta only. `instagram_video_reuploaded`: the video was copied into the ad account, and the ad still references the original post.",
                                "type": "object"
                              },
                              "isServing": {
                                "description": "LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign.",
                                "type": [
                                  "boolean",
                                  "null"
                                ]
                              },
                              "leadGenFormId": {
                                "description": "Meta: the instant form the call to action opens (`call_to_action.value.lead_gen_form_id`, or the asset feed's `call_to_actions` on a dynamic creative), the same value as the `leadGenFormId` create input. Absent on ads without a lead form.",
                                "type": "string"
                              },
                              "linkUrl": {
                                "description": "Destination URL",
                                "type": "string"
                              },
                              "mediaUrls": {
                                "description": "All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts).",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "objectStoryId": {
                                "description": "Meta creative `object_story_id` (the SHARE reference). Frequently absent, because Meta omits it for SHARE creatives. Use effectiveObjectStoryId instead.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "objectType": {
                                "description": "Meta creative object_type (e.g. SHARE, VIDEO, PRIVACY_CHECK_FAIL, POST_DELETED). Use this to render state-aware previews: when Meta moderation strips image/video fields, only thumbnailUrl at 64x64 is available.",
                                "type": "string"
                              },
                              "pageId": {
                                "description": "Facebook Page backing the creative (Meta only). What the `pageId` filter on /apis/v1/ads, /apis/v1/ads/campaigns and /apis/v1/ads/tree matches against. Absent for non-Meta ads and rare Meta creatives with no page signal.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "pinterestDescription": {
                                "type": "string"
                              },
                              "pinterestImageUrl": {
                                "type": "string"
                              },
                              "pinterestTitle": {
                                "type": "string"
                              },
                              "servingHoldReasons": {
                                "description": "LinkedIn only. Why this specific creative is not being served. Empty when it is serving.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "thumbnailUrl": {
                                "description": "Primary thumbnail/image URL",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "urlTags": {
                                "description": "Meta: the creative's `url_tags` query string appended to the destination URL.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "videoId": {
                                "description": "Meta video ID for VIDEO-type ads. Null for non-video ads. Callers that need an embeddable MP4 can call GET /{videoId}?fields=source with the page access token.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "videoUrl": {
                                "description": "Null for non-video ads.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "whatsappPhoneNumber": {
                                "description": "Explicit E.164 WhatsApp number supplied when creating a Meta boost or messaging ad. Absent when omitted by the caller or on older records.",
                                "type": "string"
                              },
                              "youtubeVideoIds": {
                                "description": "Google only. YouTube video ids behind a Video campaign ad (video and responsive video ads) or a Demand Gen video ad, same id as `youtubeVideoId` on Performance Max asset groups.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "creativeType": {
                            "description": "Creative format, classified from the media the creative carries. `null` when the creative carries no media to classify. An unsynced creative and a genuine text-only ad are indistinguishable, so neither is guessed at.",
                            "enum": [
                              "carousel",
                              "video",
                              "document",
                              "image",
                              null
                            ],
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "goal": {
                            "description": "Available goals vary by platform:",
                            "enum": [
                              "engagement",
                              "traffic",
                              "awareness",
                              "video_views",
                              "lead_generation",
                              "lead_conversion",
                              "conversions",
                              "app_promotion",
                              "catalog_sales",
                              "page_likes",
                              "page_visits",
                              "job_applicants"
                            ],
                            "type": "string"
                          },
                          "isExternal": {
                            "description": "True for ads synced from platform ad managers",
                            "type": "boolean"
                          },
                          "metrics": {
                            "anyOf": [
                              {
                                "properties": {
                                  "actionValues": {
                                    "additionalProperties": true,
                                    "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                    "type": "object"
                                  },
                                  "actions": {
                                    "additionalProperties": true,
                                    "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                    "type": "object"
                                  },
                                  "allConversions": {
                                    "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                    "type": "number"
                                  },
                                  "clicks": {
                                    "type": "integer"
                                  },
                                  "conversions": {
                                    "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                    "type": "number"
                                  },
                                  "costPerAction": {
                                    "additionalProperties": true,
                                    "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                    "type": "object"
                                  },
                                  "costPerConversion": {
                                    "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                    "type": "number"
                                  },
                                  "costPerThruplay": {
                                    "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                    "type": "number"
                                  },
                                  "cpc": {
                                    "description": "Cost per click",
                                    "type": "number"
                                  },
                                  "cpm": {
                                    "description": "Cost per 1000 impressions",
                                    "type": "number"
                                  },
                                  "ctr": {
                                    "description": "Click-through rate (%)",
                                    "type": "number"
                                  },
                                  "engagement": {
                                    "type": "integer"
                                  },
                                  "engagementBreakdown": {
                                    "additionalProperties": true,
                                    "description": "The single `engagement` total, split into the interactions behind it.",
                                    "type": "object"
                                  },
                                  "funnel": {
                                    "additionalProperties": true,
                                    "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                    "type": "object"
                                  },
                                  "impressions": {
                                    "type": "integer"
                                  },
                                  "inlineLinkClickCtr": {
                                    "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                    "type": "number"
                                  },
                                  "inlineLinkClicks": {
                                    "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                    "type": "integer"
                                  },
                                  "lastSyncedAt": {
                                    "description": "Present on individual ads only, not on campaign aggregations",
                                    "format": "date-time",
                                    "type": "string"
                                  },
                                  "outboundClicks": {
                                    "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                    "type": "integer"
                                  },
                                  "outboundClicksCtr": {
                                    "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                    "type": "number"
                                  },
                                  "purchaseValue": {
                                    "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                    "type": "number"
                                  },
                                  "reach": {
                                    "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                    "type": "integer"
                                  },
                                  "roas": {
                                    "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                    "type": "number"
                                  },
                                  "spend": {
                                    "type": "number"
                                  },
                                  "uniqueClicks": {
                                    "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                    "type": "integer"
                                  },
                                  "uniqueCtr": {
                                    "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                    "type": "number"
                                  },
                                  "video2SecWatchedActions": {
                                    "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                    "type": "integer"
                                  },
                                  "video30SecWatchedActions": {
                                    "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                    "type": "integer"
                                  },
                                  "video6SecFocusedViews": {
                                    "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                    "type": "integer"
                                  },
                                  "video6SecWatchedActions": {
                                    "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                    "type": "integer"
                                  },
                                  "videoAvgTimeWatchedActions": {
                                    "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                    "type": "number"
                                  },
                                  "videoP100WatchedActions": {
                                    "description": "Views reaching 100% of the video's length.",
                                    "type": "integer"
                                  },
                                  "videoP25WatchedActions": {
                                    "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                    "type": "integer"
                                  },
                                  "videoP50WatchedActions": {
                                    "description": "Views reaching 50% of the video's length.",
                                    "type": "integer"
                                  },
                                  "videoP75WatchedActions": {
                                    "description": "Views reaching 75% of the video's length.",
                                    "type": "integer"
                                  },
                                  "videoP95WatchedActions": {
                                    "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                    "type": "integer"
                                  },
                                  "videoPlayActions": {
                                    "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                    "type": "integer"
                                  },
                                  "videoThruplayWatchedActions": {
                                    "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                    "type": "integer"
                                  }
                                },
                                "type": "object"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "optimizationGoal": {
                            "description": "What the delivery system optimizes for, at ad-set level. The value space depends on `platform`: Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platform": {
                            "enum": [
                              "facebook",
                              "instagram",
                              "tiktok",
                              "linkedin",
                              "pinterest",
                              "google",
                              "twitter",
                              "openai",
                              "reddit",
                              "microsoft"
                            ],
                            "type": "string"
                          },
                          "platformAdAccountId": {
                            "type": "string"
                          },
                          "platformAdAccountName": {
                            "description": "Human-readable advertiser/account name (Meta `AdAccount.name`, TikTok `advertiser_name`, LinkedIn / X / Pinterest equivalents). Refreshed every sync so platform-side renames propagate within one cycle.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformAdId": {
                            "type": "string"
                          },
                          "platformAdSetId": {
                            "type": "string"
                          },
                          "platformCampaignId": {
                            "type": "string"
                          },
                          "platformCreatedAt": {
                            "description": "Platform-reported creation timestamp (Meta `created_time`, TikTok `create_time`). Read this field to sort or filter by when the ad was actually created on the platform.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformObjective": {
                            "description": "The platform's own campaign objective, verbatim, alongside the normalized `goal` it maps to. The mapping is many-to-one, so `goal` alone cannot be mapped back to it. Meta: campaign `objective` (e.g.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "promotedObject": {
                            "description": "Meta promoted object containing conversion event details. Structure varies by objective. Only present for Meta ads.",
                            "properties": {
                              "application_id": {
                                "description": "Facebook app ID",
                                "type": "string"
                              },
                              "custom_event_type": {
                                "description": "Conversion event type (e.g. PURCHASE, LEAD, COMPLETE_REGISTRATION, ADD_TO_CART)",
                                "type": "string"
                              },
                              "page_id": {
                                "description": "Facebook page ID",
                                "type": "string"
                              },
                              "pixel_id": {
                                "description": "Meta pixel ID",
                                "type": "string"
                              },
                              "product_set_id": {
                                "description": "Product catalog set ID",
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "rejectionReason": {
                            "type": "string"
                          },
                          "reviewStatus": {
                            "description": "Platform review state of this ad, independent of delivery `status` / `configuredStatus`. Absent when the platform reports no review signal.",
                            "enum": [
                              "in_review",
                              "approved",
                              "rejected",
                              "with_issues"
                            ],
                            "type": "string"
                          },
                          "roasAverageFloor": {
                            "description": "Minimum ROAS as a decimal multiplier (2.0 = 2.0x ROAS). Populated when bidStrategy is `LOWEST_COST_WITH_MIN_ROAS`.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "schedule": {
                            "description": "Delivery window as UTC instants.",
                            "properties": {
                              "endDate": {
                                "format": "date-time",
                                "type": "string"
                              },
                              "startDate": {
                                "format": "date-time",
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "servingStatuses": {
                            "description": "LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn. A campaign can report `status: ACTIVE` and still serve nothing; this array says so.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "status": {
                            "description": "Delivery status. Derived from the platform `effective_status`, so it inherits ancestor pauses (an ACTIVE ad under a PAUSED campaign reads `paused`).",
                            "enum": [
                              "active",
                              "paused",
                              "pending_review",
                              "rejected",
                              "completed",
                              "cancelled",
                              "error"
                            ],
                            "type": "string"
                          },
                          "synced": {
                            "description": "Only on GET /apis/v1/ads/{adId}. An unsynced ad has no `id`.",
                            "type": "boolean"
                          },
                          "targeting": {
                            "description": "The ad set's targeting (age, gender, geo, interests, placements, audience inclusions/exclusions). May be absent if the ad set exposes no targeting or the lookup fails.",
                            "type": "object"
                          },
                          "updatedAt": {
                            "format": "date-time",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "backfillPending": {
                      "description": "Meta only. Present and true while historical data is being backfilled.",
                      "type": "boolean"
                    },
                    "pagination": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Paginated ads"
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ads": {
                      "items": {
                        "properties": {
                          "_id": {
                            "type": "string"
                          },
                          "adSetName": {
                            "type": "string"
                          },
                          "adType": {
                            "enum": [
                              "boost",
                              "standalone"
                            ],
                            "type": "string"
                          },
                          "bidAmount": {
                            "description": "Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). Meta: `bid_amount` on the ad set (smallest-denomination int, decoded here).",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "bidStrategy": {
                            "anyOf": [
                              {
                                "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                                "enum": [
                                  "LOWEST_COST_WITHOUT_CAP",
                                  "LOWEST_COST_WITH_BID_CAP",
                                  "COST_CAP",
                                  "LOWEST_COST_WITH_MIN_ROAS"
                                ],
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Ad-set bid strategy (overrides campaign level on Meta). Populated for Meta and TikTok."
                          },
                          "budget": {
                            "properties": {
                              "amount": {
                                "type": "number"
                              },
                              "daily": {
                                "description": "LinkedIn and X only. The daily budget (LinkedIn: the parent campaign's `dailyBudget`; X: the line item's, or the campaign's when the line item has none).",
                                "type": "number"
                              },
                              "lifetime": {
                                "description": "LinkedIn and X only. The lifetime total (LinkedIn: the parent campaign's `totalBudget`; X: `total_budget_amount_local_micro`, for example the `lifetimeBudgetCap` of a boost), readable even when a daily budget is also set.",
                                "type": "number"
                              },
                              "pacing": {
                                "description": "LinkedIn only. The campaign's `pacingStrategy`: how fast LinkedIn may spend the budget. Typically LINEAR or ACCELERATED; the list is open.",
                                "type": "string"
                              },
                              "type": {
                                "enum": [
                                  "daily",
                                  "lifetime"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "campaignName": {
                            "type": "string"
                          },
                          "configuredStatus": {
                            "description": "The ad's own on/off switch as configured on the platform, independent of its parents. An ACTIVE ad under a paused ad set or campaign still reads ACTIVE here while `status` reads `paused`. Sources: Meta: `configured_status`.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "costType": {
                            "description": "LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn, refreshed on every sync rather than echoing what was passed on create. `null` for non-LinkedIn ads. `CPM`: cost per thousand impressions.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdAt": {
                            "format": "date-time",
                            "type": "string"
                          },
                          "creative": {
                            "description": "Platform-specific creative data. Fields vary by platform.",
                            "properties": {
                              "adFormat": {
                                "description": "LinkedIn only. The LinkedIn ad format, in LinkedIn's own vocabulary: STANDARD_UPDATE, SINGLE_VIDEO, CAROUSEL, NATIVE_DOCUMENT, EVENT, TEXT_AD, SPOTLIGHT, FOLLOW_COMPANY, JOBS, SPONSORED_INMAILS and others.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "assetGroup": {
                                "additionalProperties": true,
                                "description": "Google Performance Max creative assets. At least one description must be 60 characters or fewer. Texts within each list must be distinct.",
                                "type": "object"
                              },
                              "assetGroupResourceName": {
                                "description": "Google resource name of the created Performance Max asset group.",
                                "type": "string"
                              },
                              "assetResourceName": {
                                "description": "Google Display only. Resource name of the landscape marketing image asset (`creative.imageUrl`), for example customers/1234567890/assets/123.",
                                "type": "string"
                              },
                              "assets": {
                                "additionalProperties": true,
                                "description": "Google Display only. Native Google asset resource name of each image on the responsive display ad, keyed by Google's image role.",
                                "type": "object"
                              },
                              "bodies": {
                                "description": "Meta: every primary text variation of the creative (`asset_feed_spec.bodies`), the same shape as the `bodies` create input. Present only with 2 or more texts; a single text is `body`.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "body": {
                                "description": "Ad copy/text",
                                "type": "string"
                              },
                              "callToAction": {
                                "description": "Meta: the call to action type (`call_to_action.type`, or the first `asset_feed_spec.call_to_action_types` entry), e.g. LEARN_MORE or SIGN_UP.",
                                "type": "string"
                              },
                              "carouselCards": {
                                "description": "Meta only today. The carousel's cards in display order, one per Meta `link_data.child_attachments` entry, using the same field names as the `carouselCards` create input. Absent on non-carousel ads and other platforms.",
                                "items": {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "catalog": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "creativeFeatures": {
                                "additionalProperties": true,
                                "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                                "type": "object"
                              },
                              "creativeId": {
                                "description": "Meta ad creative id backing this ad, refreshed from Meta on every sync. Reusable via existingCreativeId on POST /apis/v1/ads/create, and readable raw through GET /apis/v1/ads/creatives/{creativeId}.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "description": {
                                "description": "Meta: the creative's description under the title (`link_data.description`, `video_data.link_description`, or the first `asset_feed_spec.descriptions` entry).",
                                "type": "string"
                              },
                              "descriptions": {
                                "description": "Google RSA: the description assets as objects (2 to 4). Meta: every description variation of the creative (`asset_feed_spec.descriptions`) as strings, the same shape as the `descriptions` create input.",
                                "items": {
                                  "oneOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "additionalProperties": true,
                                      "type": "object"
                                    }
                                  ]
                                },
                                "maxItems": 4,
                                "type": "array"
                              },
                              "effectiveInstagramMediaId": {
                                "description": "Meta `effective_instagram_media_id`, the Instagram media ID of the boosted post the ad's engagement lives on. Pass to GET /apis/v1/ads?effectiveInstagramMediaId= to map a Business-Manager-visible IG post back to this ad.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "effectiveObjectStoryId": {
                                "description": "Meta `effective_object_story_id`, the `{pageId}_{postId}` of the Facebook post the ad's engagement (comments) lives on.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "finalUrls": {
                                "description": "Google RSA only. Replaces final URLs. Omitted lists stay unchanged.",
                                "items": {
                                  "format": "uri",
                                  "type": "string"
                                },
                                "minItems": 1,
                                "type": "array"
                              },
                              "googleDescription": {
                                "description": "Google Ads description",
                                "type": "string"
                              },
                              "googleHeadline": {
                                "description": "Google Ads headline",
                                "type": "string"
                              },
                              "headline": {
                                "description": "Meta: the creative's title (`link_data.name`, `video_data.title`, or the first `asset_feed_spec.titles` entry). Absent when the creative has none.",
                                "type": "string"
                              },
                              "headlines": {
                                "description": "Google RSA: the headline assets as objects (3 to 15). Meta: every title variation of the creative (`asset_feed_spec.titles`) as strings, the same shape as the `headlines` create input.",
                                "items": {
                                  "oneOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "additionalProperties": true,
                                      "type": "object"
                                    }
                                  ]
                                },
                                "maxItems": 15,
                                "type": "array"
                              },
                              "imageHash": {
                                "description": "Meta: the ad image hash (`image_hash`), reusable as `imageHash` on POST /apis/v1/ads/create within the same ad account. `thumbnailUrl` and `mediaUrls` carry its stable full resolution permalink when Meta resolves it.",
                                "type": "string"
                              },
                              "imageUrl": {
                                "description": "Alternative image URL",
                                "type": "string"
                              },
                              "instagramPermalinkUrl": {
                                "description": "Meta `instagram_permalink_url`, the public Instagram post URL of the boosted media.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "instagramUserId": {
                                "description": "Meta `instagram_user_id`, the Instagram-scoped business ID that owns the boosted media.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "instagramVideoFallback": {
                                "additionalProperties": true,
                                "description": "Meta only. `instagram_video_reuploaded`: the video was copied into the ad account, and the ad still references the original post.",
                                "type": "object"
                              },
                              "isServing": {
                                "description": "LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign.",
                                "type": [
                                  "boolean",
                                  "null"
                                ]
                              },
                              "leadGenFormId": {
                                "description": "Meta: the instant form the call to action opens (`call_to_action.value.lead_gen_form_id`, or the asset feed's `call_to_actions` on a dynamic creative), the same value as the `leadGenFormId` create input. Absent on ads without a lead form.",
                                "type": "string"
                              },
                              "linkUrl": {
                                "description": "Destination URL",
                                "type": "string"
                              },
                              "mediaUrls": {
                                "description": "All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts).",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "objectStoryId": {
                                "description": "Meta creative `object_story_id` (the SHARE reference). Frequently absent, because Meta omits it for SHARE creatives. Use effectiveObjectStoryId instead.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "objectType": {
                                "description": "Meta creative object_type (e.g. SHARE, VIDEO, PRIVACY_CHECK_FAIL, POST_DELETED). Use this to render state-aware previews: when Meta moderation strips image/video fields, only thumbnailUrl at 64x64 is available.",
                                "type": "string"
                              },
                              "pageId": {
                                "description": "Facebook Page backing the creative (Meta only). What the `pageId` filter on /apis/v1/ads, /apis/v1/ads/campaigns and /apis/v1/ads/tree matches against. Absent for non-Meta ads and rare Meta creatives with no page signal.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "pinterestDescription": {
                                "type": "string"
                              },
                              "pinterestImageUrl": {
                                "type": "string"
                              },
                              "pinterestTitle": {
                                "type": "string"
                              },
                              "servingHoldReasons": {
                                "description": "LinkedIn only. Why this specific creative is not being served. Empty when it is serving.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "thumbnailUrl": {
                                "description": "Primary thumbnail/image URL",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "urlTags": {
                                "description": "Meta: the creative's `url_tags` query string appended to the destination URL.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "videoId": {
                                "description": "Meta video ID for VIDEO-type ads. Null for non-video ads. Callers that need an embeddable MP4 can call GET /{videoId}?fields=source with the page access token.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "videoUrl": {
                                "description": "Null for non-video ads.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "whatsappPhoneNumber": {
                                "description": "Explicit E.164 WhatsApp number supplied when creating a Meta boost or messaging ad. Absent when omitted by the caller or on older records.",
                                "type": "string"
                              },
                              "youtubeVideoIds": {
                                "description": "Google only. YouTube video ids behind a Video campaign ad (video and responsive video ads) or a Demand Gen video ad, same id as `youtubeVideoId` on Performance Max asset groups.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "creativeType": {
                            "description": "Creative format, classified from the media the creative carries. `null` when the creative carries no media to classify. An unsynced creative and a genuine text-only ad are indistinguishable, so neither is guessed at.",
                            "enum": [
                              "carousel",
                              "video",
                              "document",
                              "image",
                              null
                            ],
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "goal": {
                            "description": "Available goals vary by platform:",
                            "enum": [
                              "engagement",
                              "traffic",
                              "awareness",
                              "video_views",
                              "lead_generation",
                              "lead_conversion",
                              "conversions",
                              "app_promotion",
                              "catalog_sales",
                              "page_likes",
                              "page_visits",
                              "job_applicants"
                            ],
                            "type": "string"
                          },
                          "isExternal": {
                            "description": "True for ads synced from platform ad managers",
                            "type": "boolean"
                          },
                          "metrics": {
                            "anyOf": [
                              {
                                "properties": {
                                  "actionValues": {
                                    "additionalProperties": true,
                                    "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                    "type": "object"
                                  },
                                  "actions": {
                                    "additionalProperties": true,
                                    "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                    "type": "object"
                                  },
                                  "allConversions": {
                                    "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                    "type": "number"
                                  },
                                  "clicks": {
                                    "type": "integer"
                                  },
                                  "conversions": {
                                    "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                    "type": "number"
                                  },
                                  "costPerAction": {
                                    "additionalProperties": true,
                                    "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                    "type": "object"
                                  },
                                  "costPerConversion": {
                                    "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                    "type": "number"
                                  },
                                  "costPerThruplay": {
                                    "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                    "type": "number"
                                  },
                                  "cpc": {
                                    "description": "Cost per click",
                                    "type": "number"
                                  },
                                  "cpm": {
                                    "description": "Cost per 1000 impressions",
                                    "type": "number"
                                  },
                                  "ctr": {
                                    "description": "Click-through rate (%)",
                                    "type": "number"
                                  },
                                  "engagement": {
                                    "type": "integer"
                                  },
                                  "engagementBreakdown": {
                                    "additionalProperties": true,
                                    "description": "The single `engagement` total, split into the interactions behind it.",
                                    "type": "object"
                                  },
                                  "funnel": {
                                    "additionalProperties": true,
                                    "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                    "type": "object"
                                  },
                                  "impressions": {
                                    "type": "integer"
                                  },
                                  "inlineLinkClickCtr": {
                                    "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                    "type": "number"
                                  },
                                  "inlineLinkClicks": {
                                    "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                    "type": "integer"
                                  },
                                  "lastSyncedAt": {
                                    "description": "Present on individual ads only, not on campaign aggregations",
                                    "format": "date-time",
                                    "type": "string"
                                  },
                                  "outboundClicks": {
                                    "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                    "type": "integer"
                                  },
                                  "outboundClicksCtr": {
                                    "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                    "type": "number"
                                  },
                                  "purchaseValue": {
                                    "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                    "type": "number"
                                  },
                                  "reach": {
                                    "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                    "type": "integer"
                                  },
                                  "roas": {
                                    "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                    "type": "number"
                                  },
                                  "spend": {
                                    "type": "number"
                                  },
                                  "uniqueClicks": {
                                    "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                    "type": "integer"
                                  },
                                  "uniqueCtr": {
                                    "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                    "type": "number"
                                  },
                                  "video2SecWatchedActions": {
                                    "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                    "type": "integer"
                                  },
                                  "video30SecWatchedActions": {
                                    "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                    "type": "integer"
                                  },
                                  "video6SecFocusedViews": {
                                    "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                    "type": "integer"
                                  },
                                  "video6SecWatchedActions": {
                                    "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                    "type": "integer"
                                  },
                                  "videoAvgTimeWatchedActions": {
                                    "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                    "type": "number"
                                  },
                                  "videoP100WatchedActions": {
                                    "description": "Views reaching 100% of the video's length.",
                                    "type": "integer"
                                  },
                                  "videoP25WatchedActions": {
                                    "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                    "type": "integer"
                                  },
                                  "videoP50WatchedActions": {
                                    "description": "Views reaching 50% of the video's length.",
                                    "type": "integer"
                                  },
                                  "videoP75WatchedActions": {
                                    "description": "Views reaching 75% of the video's length.",
                                    "type": "integer"
                                  },
                                  "videoP95WatchedActions": {
                                    "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                    "type": "integer"
                                  },
                                  "videoPlayActions": {
                                    "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                    "type": "integer"
                                  },
                                  "videoThruplayWatchedActions": {
                                    "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                    "type": "integer"
                                  }
                                },
                                "type": "object"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "optimizationGoal": {
                            "description": "What the delivery system optimizes for, at ad-set level. The value space depends on `platform`: Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platform": {
                            "enum": [
                              "facebook",
                              "instagram",
                              "tiktok",
                              "linkedin",
                              "pinterest",
                              "google",
                              "twitter",
                              "openai",
                              "reddit",
                              "microsoft"
                            ],
                            "type": "string"
                          },
                          "platformAdAccountId": {
                            "type": "string"
                          },
                          "platformAdAccountName": {
                            "description": "Human-readable advertiser/account name (Meta `AdAccount.name`, TikTok `advertiser_name`, LinkedIn / X / Pinterest equivalents). Refreshed every sync so platform-side renames propagate within one cycle.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformAdId": {
                            "type": "string"
                          },
                          "platformAdSetId": {
                            "type": "string"
                          },
                          "platformCampaignId": {
                            "type": "string"
                          },
                          "platformCreatedAt": {
                            "description": "Platform-reported creation timestamp (Meta `created_time`, TikTok `create_time`). Read this field to sort or filter by when the ad was actually created on the platform.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformObjective": {
                            "description": "The platform's own campaign objective, verbatim, alongside the normalized `goal` it maps to. The mapping is many-to-one, so `goal` alone cannot be mapped back to it. Meta: campaign `objective` (e.g.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "promotedObject": {
                            "description": "Meta promoted object containing conversion event details. Structure varies by objective. Only present for Meta ads.",
                            "properties": {
                              "application_id": {
                                "description": "Facebook app ID",
                                "type": "string"
                              },
                              "custom_event_type": {
                                "description": "Conversion event type (e.g. PURCHASE, LEAD, COMPLETE_REGISTRATION, ADD_TO_CART)",
                                "type": "string"
                              },
                              "page_id": {
                                "description": "Facebook page ID",
                                "type": "string"
                              },
                              "pixel_id": {
                                "description": "Meta pixel ID",
                                "type": "string"
                              },
                              "product_set_id": {
                                "description": "Product catalog set ID",
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "rejectionReason": {
                            "type": "string"
                          },
                          "reviewStatus": {
                            "description": "Platform review state of this ad, independent of delivery `status` / `configuredStatus`. Absent when the platform reports no review signal.",
                            "enum": [
                              "in_review",
                              "approved",
                              "rejected",
                              "with_issues"
                            ],
                            "type": "string"
                          },
                          "roasAverageFloor": {
                            "description": "Minimum ROAS as a decimal multiplier (2.0 = 2.0x ROAS). Populated when bidStrategy is `LOWEST_COST_WITH_MIN_ROAS`.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "schedule": {
                            "description": "Delivery window as UTC instants.",
                            "properties": {
                              "endDate": {
                                "format": "date-time",
                                "type": "string"
                              },
                              "startDate": {
                                "format": "date-time",
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "servingStatuses": {
                            "description": "LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn. A campaign can report `status: ACTIVE` and still serve nothing; this array says so.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "status": {
                            "description": "Delivery status. Derived from the platform `effective_status`, so it inherits ancestor pauses (an ACTIVE ad under a PAUSED campaign reads `paused`).",
                            "enum": [
                              "active",
                              "paused",
                              "pending_review",
                              "rejected",
                              "completed",
                              "cancelled",
                              "error"
                            ],
                            "type": "string"
                          },
                          "synced": {
                            "description": "Only on GET /apis/v1/ads/{adId}. An unsynced ad has no `id`.",
                            "type": "boolean"
                          },
                          "targeting": {
                            "description": "The ad set's targeting (age, gender, geo, interests, placements, audience inclusions/exclusions). May be absent if the ad set exposes no targeting or the lookup fails.",
                            "type": "object"
                          },
                          "updatedAt": {
                            "format": "date-time",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "backfillPending": {
                      "description": "Always true on this response. Part of the requested range is still being backfilled; retry until the request returns 200.",
                      "type": "boolean"
                    },
                    "pagination": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "backfillPending"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Meta only. Historical data is incomplete and backfill remains pending."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List ads",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ads@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "758eb91f56c7db77bd2322d3e3e5e15b4f0aaf5c644ceb695eb7fab8d374dcfb"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads",
          "method": "GET",
          "path": "/apis/v1/ads"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads"
      }
    },
    "/apis/v1/ads/accounts": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the ad accounts a connection can manage, such as Meta ad accounts, TikTok advertisers or Google Ads customers. Returns the platform ad accounts available for the given account (e.g. Meta ad accounts, TikTok advertiser IDs, Google Ads customer IDs). ### Meta Meta business-login accounts use their own system-user token.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Filter response to a single platform ad account ID (e.g. `act_123` for Meta, advertiser_id for TikTok). Returns at most one item.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Clamp the returned `accounts[]` length. Useful for typeahead pickers on agency tokens with hundreds of advertisers.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`true` returns only the ad accounts this connection accepts as `adAccountId` on the other /apis/v1/ads endpoints, i.e. those inside its ad-account selection (every item then has `selected: true`).",
            "in": "query",
            "name": "inScopeOnly",
            "required": false,
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "accounts": {
                      "items": {
                        "properties": {
                          "accountStatus": {
                            "description": "The platform's own account status, forwarded unchanged. No JSON type is declared because it differs per platform: Meta sends an integer; Google, TikTok and Pinterest send a string."
                          },
                          "approvalStatus": {
                            "description": "X and Reddit only. X's own ad account approval status, or Reddit's `admin_approval`. Observed X values are `ACCEPTED`, `PENDING` and `REJECTED`, but X does not publish the full vocabulary, so treat an unrecognised value as not usable.",
                            "type": "string"
                          },
                          "balance": {
                            "description": "TikTok only. Total balance the advertiser can spend (cash plus grant), in whole units of `currency`.",
                            "type": "number"
                          },
                          "billingStatus": {
                            "description": "Meta only. Whether the ad account has a payment method:",
                            "enum": [
                              "ok",
                              "missing",
                              "unknown"
                            ],
                            "type": "string"
                          },
                          "businessId": {
                            "description": "Meta only. Owning Business Manager ID when available on the grant.",
                            "type": "string"
                          },
                          "businessName": {
                            "description": "Owning business name when supplied by the platform.",
                            "type": "string"
                          },
                          "cashBalance": {
                            "description": "TikTok only. Cash part of `balance`, in whole units of `currency`. Absent when the connection has no finance role in the advertiser's Business Center.",
                            "type": "number"
                          },
                          "currency": {
                            "type": "string"
                          },
                          "disableReason": {
                            "description": "Meta only. Meta's `disable_reason` code, forwarded unchanged. Present when `accountStatus` is `2` (DISABLED) and Meta gives a reason; this separates a policy action from a payment problem.",
                            "type": "integer"
                          },
                          "fundingSource": {
                            "description": "Meta only. Meta's `funding_source` ID for the ad account, forwarded unchanged. ABSENT both when this connection's token cannot see billing and when the account has no payment method; read `billingStatus` to tell the two apart.",
                            "type": "string"
                          },
                          "fundingSourceDetails": {
                            "description": "Meta only. Meta's `funding_source_details` object, forwarded unchanged. ABSENT under exactly the same conditions as `fundingSource`, never sent as null or as an empty object. Read `billingStatus` for what the absence means.",
                            "properties": {
                              "displayString": {
                                "description": "Meta's own human-readable label for the funding instrument, e.g. 'Available Balance (EUR)' or a masked card. Meta composes this string; do not parse it.",
                                "type": "string"
                              },
                              "id": {
                                "description": "Meta's ID for the funding instrument. Matches `fundingSource`.",
                                "type": "string"
                              },
                              "type": {
                                "description": "Meta's raw numeric funding-source type, forwarded unchanged. Meta publishes no mapping from these numbers to payment-method kinds, so none is documented here and none should be inferred.",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "grantBalance": {
                            "description": "TikTok only. Grant (ad credit) part of `balance`, in whole units of `currency`. Absent when the connection has no finance role in the advertiser's Business Center.",
                            "type": "number"
                          },
                          "id": {
                            "description": "Platform ad account ID (e.g. act_123)",
                            "type": "string"
                          },
                          "minimumDailyBudget": {
                            "description": "Meta only. Minimum daily budget for the account, in the account currency's major units. This is the impressions-billed minimum; other billing events have higher minimums. Absent when the connected token cannot read it.",
                            "type": "number"
                          },
                          "name": {
                            "type": "string"
                          },
                          "selectable": {
                            "description": "Meta and X only. Whether the account can create/run ads now. Always present on every Meta and X account. Absent (treat as true) on other platforms.",
                            "type": "boolean"
                          },
                          "selected": {
                            "description": "Always present. True when the ad account is in this connection's ad-account selection, or when the connection has no selection (then every ad account is usable). For a posting account (e.g.",
                            "type": "boolean"
                          },
                          "status": {
                            "description": "LinkedIn only. LinkedIn's own ad account status. In practice always `ACTIVE`, because the LinkedIn query filters to active accounts. Meta, Google, TikTok and Pinterest report `accountStatus` instead; X reports `approvalStatus`.",
                            "type": "string"
                          },
                          "timezone": {
                            "description": "Reddit only. The ad account's time zone as Reddit reports it (`time_zone_id`). Schedules on Reddit ads are read in this zone.",
                            "type": "string"
                          },
                          "timezoneName": {
                            "description": "IANA timezone of the ad account (Meta only). Drives daily-budget reset and Insights day boundaries.",
                            "type": "string"
                          },
                          "timezoneOffsetHoursUtc": {
                            "description": "Signed UTC offset in hours, reflecting current DST (Meta only).",
                            "type": "number"
                          },
                          "type": {
                            "description": "Reddit only. Reddit's ad account type, forwarded unchanged.",
                            "type": "string"
                          },
                          "unusableReason": {
                            "description": "Meta and X only. Always present on every Meta and X account. Human-readable reason when selectable is false; null when selectable.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "cachedAt": {
                      "description": "Google only. When this list was fetched from Google. Null when it was never served from cache. Absent on other platforms.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "stale": {
                      "description": "Google only. True when Google's daily API quota was exhausted and this is the last successful fetch, not a live read. Absent on other platforms.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad accounts"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List ad accounts",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_accounts@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "4007a90307fca1ef9a9bab31873d9fd9cbd7cf212e44659e26d1cd1078bc1d69"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts",
          "method": "GET",
          "path": "/apis/v1/ads/accounts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts"
      },
      "patch": {
        "description": "Ad Accounts. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Changes ad account settings, including its spend cap. Changes a Meta ad account's name, spend cap or default EU DSA beneficiary and payor. Pass any combination of fields. On Google Ads, only URL tracking fields apply (see below). Other platforms return 400. ### Spend cap `spendCap` is the total the account may spend before Meta pauses every campaign in it, in whole units of the account currency. `spendCap: null` removes the cap.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_accounts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_123456789",
                "connectionId": "adc_7f3k2m9q",
                "spendCap": 500
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Meta ad account ID (act_...)",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "defaultDsaBeneficiary": {
                    "description": "Legal entity benefiting from ads on this ad account",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "defaultDsaPayor": {
                    "description": "Legal entity paying for ads on this ad account. Defaults to defaultDsaBeneficiary when omitted. Requires defaultDsaBeneficiary.",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "finalUrlSuffix": {
                    "description": "Google only. Account final URL suffix (customer.final_url_suffix); an empty string clears it.",
                    "type": "string"
                  },
                  "name": {
                    "description": "New ad account name.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "resetAmountSpent": {
                    "description": "Restart the amount counted against the cap from zero. Cannot be combined with spendCap null.",
                    "type": "boolean"
                  },
                  "spendCap": {
                    "description": "Account spend cap in whole currency units; null removes it.",
                    "type": [
                      "number",
                      "null"
                    ]
                  },
                  "trackingUrlTemplate": {
                    "description": "Google only. Account tracking template (customer.tracking_url_template); an empty string clears it.",
                    "type": "string"
                  }
                },
                "required": [
                  "adAccountId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "dsaDefaults": {
                      "description": "Present when defaultDsaBeneficiary was passed.",
                      "properties": {
                        "beneficiary": {
                          "type": "string"
                        },
                        "payor": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "settings": {
                      "description": "Present when name, spendCap or resetAmountSpent was passed.",
                      "properties": {
                        "amountSpent": {
                          "type": "number"
                        },
                        "balance": {
                          "type": "number"
                        },
                        "currency": {
                          "type": "string"
                        },
                        "fundingSource": {
                          "properties": {
                            "displayString": {
                              "type": "string"
                            },
                            "type": {
                              "type": "integer"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "name": {
                          "type": "string"
                        },
                        "spendCap": {
                          "type": [
                            "number",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    },
                    "urlTracking": {
                      "description": "Google only. The URL tracking fields written.",
                      "properties": {
                        "finalUrlSuffix": {
                          "type": "string"
                        },
                        "trackingUrlTemplate": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Settings updated (each block re-read from Meta after the write)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update ad account settings",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_account@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "34584a3bff6f2123ef6e2160848cff03086bd7a6b42488706dccf05c552a41ae"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_accounts",
          "method": "PATCH",
          "path": "/apis/v1/ads/accounts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_accounts"
      },
      "post": {
        "description": "Ad Accounts. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates a new ad account. validateOnly=true checks the request without acting and needs no confirmation. Creates a new Meta ad account in the user's own business portfolio, or a Google Ads client account under a manager (MCC) account the connection reaches. Billing must then be set up on the platform. Meta (omit `platform` or send `meta`). Creates a durable Meta ad account in the end user's own business portfolio using their connected Meta Ads token. ### Meta requirements\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_accounts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "businessId": "123456789012345",
                "connectionId": "adc_7f3k2m9q",
                "currency": "EUR",
                "name": "Customer advertising",
                "timezoneId": 1
              },
              "schema": {
                "additionalProperties": true,
                "oneOf": [
                  {
                    "additionalProperties": false,
                    "properties": {
                      "adAccountCreatedFromBmFlag": {
                        "description": "Meta Business Manager creation flag.",
                        "type": "boolean"
                      },
                      "businessId": {
                        "description": "Business portfolio that will own the account.",
                        "pattern": "^[1-9][0-9]*$",
                        "type": "string"
                      },
                      "connectionId": {
                        "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                        "pattern": "^adc_[0-9A-Za-z]+$",
                        "type": "string"
                      },
                      "currency": {
                        "description": "Uppercase ISO 4217 currency supported by Meta.",
                        "pattern": "^[A-Z]{3}$",
                        "type": "string"
                      },
                      "endAdvertiser": {
                        "default": "NONE",
                        "description": "End advertiser business or page ID. NONE uses the owning business.",
                        "pattern": "^(NONE|[1-9][0-9]*)$",
                        "type": "string"
                      },
                      "fundingId": {
                        "description": "Existing Meta funding reference. Does not add a payment method.",
                        "pattern": "^[1-9][0-9]*$",
                        "type": "string"
                      },
                      "invoice": {
                        "description": "Request Meta invoicing. Eligibility is determined by Meta.",
                        "type": "boolean"
                      },
                      "invoiceGroupId": {
                        "description": "Existing Meta invoice group ID.",
                        "pattern": "^[1-9][0-9]*$",
                        "type": "string"
                      },
                      "invoicingEmails": {
                        "description": "Addresses for Meta invoices.",
                        "items": {
                          "format": "email",
                          "type": "string"
                        },
                        "maxItems": 100,
                        "minItems": 1,
                        "type": "array"
                      },
                      "io": {
                        "description": "Meta insertion-order invoicing option.",
                        "type": "boolean"
                      },
                      "mediaAgency": {
                        "default": "NONE",
                        "description": "Media agency business or page ID. NONE for self-serve customers.",
                        "pattern": "^(NONE|[1-9][0-9]*)$",
                        "type": "string"
                      },
                      "name": {
                        "description": "Ad account name. Whitespace is trimmed.",
                        "maxLength": 255,
                        "minLength": 1,
                        "type": "string"
                      },
                      "partner": {
                        "default": "NONE",
                        "description": "Partner business or page ID. NONE for self-serve customers.",
                        "pattern": "^(NONE|[1-9][0-9]*)$",
                        "type": "string"
                      },
                      "platform": {
                        "description": "Optional. Omit it or send meta for a Meta ad account. Filled from the connection when omitted.",
                        "enum": [
                          "meta"
                        ],
                        "type": "string"
                      },
                      "poNumber": {
                        "description": "Purchase order number.",
                        "maxLength": 255,
                        "minLength": 1,
                        "type": "string"
                      },
                      "timezoneId": {
                        "description": "Numeric Meta timezone ID from the linked timezone list. For example 1 is America/Los_Angeles.",
                        "maximum": 4294967295,
                        "minimum": 0,
                        "type": "integer"
                      }
                    },
                    "required": [
                      "businessId",
                      "currency",
                      "name",
                      "timezoneId"
                    ],
                    "type": "object"
                  },
                  {
                    "additionalProperties": false,
                    "properties": {
                      "connectionId": {
                        "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                        "pattern": "^adc_[0-9A-Za-z]+$",
                        "type": "string"
                      },
                      "currency": {
                        "description": "Uppercase ISO 4217 currency. Cannot be changed after creation.",
                        "pattern": "^[A-Z]{3}$",
                        "type": "string"
                      },
                      "managerCustomerId": {
                        "description": "Manager (MCC) customer id without dashes. The new account is created under it. List reachable managers with GET /apis/v1/ads/accounts/hierarchy.",
                        "pattern": "^[0-9]+$",
                        "type": "string"
                      },
                      "name": {
                        "description": "Account name. Whitespace is trimmed.",
                        "maxLength": 255,
                        "minLength": 1,
                        "type": "string"
                      },
                      "platform": {
                        "description": "Filled from the connection when omitted.",
                        "enum": [
                          "google"
                        ],
                        "type": "string"
                      },
                      "timeZone": {
                        "description": "IANA time zone name, for example Europe/Madrid. Cannot be changed after creation.",
                        "type": "string"
                      },
                      "validateOnly": {
                        "default": false,
                        "description": "Ask Google to validate the request without creating the account.",
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "currency",
                      "managerCustomerId",
                      "name",
                      "timeZone"
                    ],
                    "type": "object"
                  }
                ],
                "properties": {
                  "adAccountCreatedFromBmFlag": {
                    "description": "Meta Business Manager creation flag.",
                    "type": "boolean"
                  },
                  "businessId": {
                    "description": "Business portfolio that will own the account.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "currency": {
                    "description": "Uppercase ISO 4217 currency supported by Meta.",
                    "type": "string"
                  },
                  "endAdvertiser": {
                    "description": "End advertiser business or page ID. NONE uses the owning business.",
                    "type": "string"
                  },
                  "fundingId": {
                    "description": "Existing Meta funding reference. Does not add a payment method.",
                    "type": "string"
                  },
                  "invoice": {
                    "description": "Request Meta invoicing. Eligibility is determined by Meta.",
                    "type": "boolean"
                  },
                  "invoiceGroupId": {
                    "description": "Existing Meta invoice group ID.",
                    "type": "string"
                  },
                  "invoicingEmails": {
                    "description": "Addresses for Meta invoices.",
                    "type": "array"
                  },
                  "io": {
                    "description": "Meta insertion-order invoicing option.",
                    "type": "boolean"
                  },
                  "managerCustomerId": {
                    "description": "Manager (MCC) customer id without dashes. The new account is created under it. List reachable managers with GET /apis/v1/ads/accounts/hierarchy.",
                    "type": "string"
                  },
                  "mediaAgency": {
                    "description": "Media agency business or page ID. NONE for self-serve customers.",
                    "type": "string"
                  },
                  "name": {
                    "description": "Ad account name. Whitespace is trimmed.",
                    "type": "string"
                  },
                  "partner": {
                    "description": "Partner business or page ID. NONE for self-serve customers.",
                    "type": "string"
                  },
                  "platform": {
                    "description": "Optional. Omit it or send meta for a Meta ad account. Filled from the connection when omitted.",
                    "enum": [
                      "meta",
                      "google"
                    ],
                    "type": "string"
                  },
                  "poNumber": {
                    "description": "Purchase order number.",
                    "type": "string"
                  },
                  "timeZone": {
                    "description": "IANA time zone name, for example Europe/Madrid. Cannot be changed after creation.",
                    "type": "string"
                  },
                  "timezoneId": {
                    "description": "Numeric Meta timezone ID from the linked timezone list. For example 1 is America/Los_Angeles.",
                    "type": "integer"
                  },
                  "validateOnly": {
                    "description": "Ask Google to validate the request without creating the account.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "currency",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "managerCustomerId": {
                      "type": "string"
                    },
                    "platform": {
                      "enum": [
                        "google"
                      ],
                      "type": "string"
                    },
                    "validateOnly": {
                      "description": "Always true on a 200.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "managerCustomerId",
                    "platform",
                    "validateOnly"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Google validateOnly request accepted by Google. Nothing was created."
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "properties": {
                        "adAccountId": {
                          "description": "New Meta ad account ID for subsequent ads calls.",
                          "pattern": "^act_[0-9]+$",
                          "type": "string"
                        },
                        "adsManagerUrl": {
                          "description": "Open the created account in Ads Manager.",
                          "format": "uri",
                          "type": "string"
                        },
                        "businessId": {
                          "description": "Owning business portfolio ID.",
                          "type": "string"
                        },
                        "connectionUpdated": {
                          "description": "Whether the connection scope and discovery schedule were updated.",
                          "type": "boolean"
                        },
                        "nextSteps": {
                          "description": "Payment setup instructions for the user.",
                          "type": "string"
                        },
                        "paymentMethodRequired": {
                          "description": "Always true as a delivery prerequisite. This is not a live funding-source check. Confirm payment or invoicing in Ads Manager.",
                          "type": "boolean"
                        },
                        "warnings": {
                          "description": "Recovery instructions if the account could not be attached to the connection.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "adAccountId",
                        "adsManagerUrl",
                        "businessId",
                        "connectionUpdated",
                        "nextSteps",
                        "paymentMethodRequired",
                        "warnings"
                      ],
                      "type": "object"
                    },
                    {
                      "properties": {
                        "adAccountId": {
                          "description": "New Google Ads customer id for subsequent ads calls.",
                          "pattern": "^[0-9]+$",
                          "type": "string"
                        },
                        "connectionUpdated": {
                          "description": "Whether the customer was added to the connection and discovery was scheduled. When false the account exists: reconnect Google Ads instead of creating it again.",
                          "type": "boolean"
                        },
                        "managerCustomerId": {
                          "description": "Manager the account was created under.",
                          "type": "string"
                        },
                        "nextSteps": {
                          "description": "Billing setup instructions for the user.",
                          "type": "string"
                        },
                        "paymentMethodRequired": {
                          "description": "Always true. The account has no billing until it is set up in Google Ads.",
                          "type": "boolean"
                        },
                        "platform": {
                          "enum": [
                            "google"
                          ],
                          "type": "string"
                        },
                        "validateOnly": {
                          "description": "Always false on a 201.",
                          "type": "boolean"
                        },
                        "warnings": {
                          "description": "Recovery instructions if the account could not be attached to the connection.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "adAccountId",
                        "connectionUpdated",
                        "managerCustomerId",
                        "nextSteps",
                        "paymentMethodRequired",
                        "platform",
                        "validateOnly",
                        "warnings"
                      ],
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Ad account created. Check connectionUpdated and the billing instructions."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create ad account",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_account@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "f14ef6cab8d3b700b347ea862c08b6a4f4970db39eec983f1c05e660bbd6b0cf"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_accounts",
          "method": "POST",
          "path": "/apis/v1/ads/accounts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_accounts"
      }
    },
    "/apis/v1/ads/accounts/billing": {
      "get": {
        "description": "Ad Accounts. Read only. Reads the payments accounts a Google Ads account can be billed to, plus its billing setups and account budgets. ### Payments accounts Payments accounts come from Google's PaymentsAccountService, read as the manager above the customer. They are the monthly invoicing (consolidated billing) accounts of that manager.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_billing",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google Ads customer id, digits only. Defaults to the connection's selected customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "accountBudgets": {
                      "items": {
                        "properties": {
                          "accountBudgetId": {
                            "type": "string"
                          },
                          "approvedSpendingLimitMicros": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "approvedSpendingLimitType": {
                            "description": "INFINITE for an unlimited budget.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "billingSetupId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "pendingProposalId": {
                            "description": "Account budget proposal still waiting for Google's review.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "enum": [
                              "PENDING",
                              "APPROVED",
                              "CANCELLED",
                              "UNKNOWN"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "billingSetups": {
                      "items": {
                        "properties": {
                          "billingSetupId": {
                            "type": "string"
                          },
                          "endDateTime": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "paymentsAccountId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "startDateTime": {
                            "description": "In the account time zone, as Google returns it.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "description": "APPROVED_HELD means approved but waiting for its first account budget to be approved.",
                            "enum": [
                              "PENDING",
                              "APPROVED_HELD",
                              "APPROVED",
                              "CANCELLED",
                              "UNKNOWN"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "cachedAt": {
                      "description": "When this data was fetched from Google. Null when the cache is unavailable.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "paymentsAccounts": {
                      "items": {
                        "properties": {
                          "currency": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "payingManagerCustomerId": {
                            "description": "Manager whose monthly invoice pays this account.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "paymentsAccountId": {
                            "description": "Format 1234-5678-9012-3456. Pass it to POST /apis/v1/ads/accounts/billing.",
                            "type": "string"
                          },
                          "paymentsProfileId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "pendingBudgetProposals": {
                      "description": "New account budgets proposed but not yet approved by Google. A setup with one is not reused by the POST.",
                      "items": {
                        "properties": {
                          "accountBudgetProposalId": {
                            "type": "string"
                          },
                          "billingSetupId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when Google's quota was exhausted and this is the last successful fetch.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Billing state of the customer"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get ad account billing",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_account_billing@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "73af91022d5fc032cc3708a5373dd741a5851d66b4ac89d09042cdd79f139730"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_billing",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/billing"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_billing"
      },
      "post": {
        "description": "Ad Accounts. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Sets up billing for the ad account, with its spending limit. validateOnly=true checks the request without acting and needs no confirmation. Bills a Google Ads account to a monthly invoicing payments account of a manager above it, and proposes its account budget, so the account can serve without anyone opening Google Ads. ### Monthly invoicing only Google's API cannot add a card or other payment method.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_accounts_billing",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "5551234567",
                "connectionId": "adc_7f3k2m9q",
                "paymentsAccountId": "1234-5678-9012-3456",
                "spendingLimit": 5000
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Google Ads customer id to bill, digits only.",
                    "pattern": "^[0-9]+$",
                    "type": "string"
                  },
                  "budgetName": {
                    "default": "AIsa account budget",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "paymentsAccountId": {
                    "description": "Monthly invoicing payments account from GET /apis/v1/ads/accounts/billing.",
                    "pattern": "^\\d{4}-\\d{4}-\\d{4}-\\d{4}$",
                    "type": "string"
                  },
                  "purchaseOrderNumber": {
                    "description": "Printed on the invoice. No effect on delivery.",
                    "maxLength": 64,
                    "minLength": 1,
                    "type": "string"
                  },
                  "spendingLimit": {
                    "description": "Account budget cap in the account currency. Omit for an unlimited budget.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "validateOnly": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "adAccountId",
                  "paymentsAccountId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "accountBudgetProposalId": {
                      "description": "Always null for validateOnly.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "billingSetupId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "paymentsAccountId": {
                      "type": "string"
                    },
                    "paymentsAccountName": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "reusedBillingSetup": {
                      "type": "boolean"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "validateOnly: checks passed, nothing created. billingSetupId is set when an existing setup would be reused."
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "accountBudgetProposalId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "billingSetupId": {
                      "type": "string"
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "nextSteps": {
                      "type": "string"
                    },
                    "paymentsAccountId": {
                      "type": "string"
                    },
                    "paymentsAccountName": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "reusedBillingSetup": {
                      "description": "True when an existing setup on the same payments account without a budget was completed.",
                      "type": "boolean"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Billing setup created (or reused) and account budget proposed."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Set up ad account billing (monthly invoicing)",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.set_up_ad_account_billing@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "7c921944f90c5611c9459a501303f76b21c75a36adf5a27da3326c939aae8d9c"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_accounts_billing",
          "method": "POST",
          "path": "/apis/v1/ads/accounts/billing"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_accounts_billing"
      }
    },
    "/apis/v1/ads/accounts/callouts": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Detaches a callout from the Google Ads account level, leaving it on any campaigns or ad groups that still use it. Removes the customer_asset attachment only. The underlying shared asset and its campaign or ad-group attachments remain. Fields go in the query string. A JSON body with the same fields is also accepted and, when sent, the query string is ignored.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_accounts_callouts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Numeric Google Ads asset id.",
            "in": "query",
            "name": "assetId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "removed": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove account callout",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_account_callout@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "22617188c0a4381f7f91846d41e35f1540c601ebfabe2ef5f0ea9e99abbf1e45"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_accounts_callouts",
          "method": "DELETE",
          "path": "/apis/v1/ads/accounts/callouts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_accounts_callouts"
      },
      "get": {
        "description": "Ad Accounts. Read only. Lists the callouts attached at account level in Google Ads, which can show on ads across all campaigns. Fresh reads are cached for 10 minutes; exhausted quota may return the last successful read with stale=true. Inherited assets are not included. Preserves Google RMF C.75 account-level callouts.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_callouts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "description": "Alias of adAccountId, kept for existing callers",
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "Time of the cached Google read. Null when no cache was used.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "callouts": {
                      "items": {
                        "properties": {
                          "assetId": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "text": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "stale": {
                      "description": "True when exhausted quota required returning the last successful read.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List account callouts",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_account_callouts@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0109bda93164537a58fc0cddd75178a2be678609c5f334726b5ce488f80b8de2"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_callouts",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/callouts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_callouts"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Creates callouts and attaches them at account level in Google Ads so they can show on ads across all campaigns. Creates assets and customer_asset links for this Google customer. Links apply at account level.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_accounts_callouts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "callouts": [
                  "Fast setup"
                ],
                "connectionId": "adc_7f3k2m9q"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "callouts": {
                    "items": {
                      "maxLength": 25,
                      "minLength": 1,
                      "type": "string"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  }
                },
                "required": [
                  "callouts"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "callouts": {
                      "items": {
                        "properties": {
                          "assetId": {
                            "type": "string"
                          },
                          "text": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "customerId": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets created and attached."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Add account callouts",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.add_account_callouts@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "4d9ce34cbf3e59d5c646dd496f34665828b825473e25488623959baacd5177c5"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_accounts_callouts",
          "method": "POST",
          "path": "/apis/v1/ads/accounts/callouts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_accounts_callouts"
      },
      "put": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Edits existing Google Ads callouts in place; the change applies everywhere that callout is used. Send updates with assetResourceName and the fields to change. An asset is shared: changes affect every attachment using it. Omitted fields stay unchanged. The operation consumes the Google operations budget and invalidates affected cached lists.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_accounts_callouts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "updates": [
                  {
                    "assetResourceName": "customers/1234567890/assets/123",
                    "calloutAsset": {
                      "calloutText": "Simple integration"
                    }
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "updates": {
                    "items": {
                      "description": "Provide at least one field belonging to this asset type.",
                      "properties": {
                        "assetResourceName": {
                          "description": "Asset resource name returned by a list operation. Must belong to the selected customer.",
                          "pattern": "^customers/\\d+/assets/\\d+$",
                          "type": "string"
                        },
                        "calloutAsset": {
                          "properties": {
                            "calloutText": {
                              "maxLength": 25,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "calloutText"
                          ],
                          "type": "object"
                        }
                      },
                      "required": [
                        "assetResourceName"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "updates"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "updated": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update account callouts",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_account_callouts@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "2bbf1298482ff75de49c619ba240ba7ff9ed7a953caf47f40a2e77ae266ae8ef"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_accounts_callouts",
          "method": "PUT",
          "path": "/apis/v1/ads/accounts/callouts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_accounts_callouts"
      }
    },
    "/apis/v1/ads/accounts/finance": {
      "get": {
        "description": "Ad Accounts. Read only. Shows a Meta ad account's balance, total spend, spend cap and funding source. Finances of one Meta ad account: prepaid `balance`, lifetime `amountSpent`, account `spendCap` (null = no cap) and the `fundingSource`. Money values are converted from Meta's minor units to whole units of `currency`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_finance",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "amountSpent": {
                      "description": "Lifetime amount spent in whole currency units.",
                      "type": "number"
                    },
                    "balance": {
                      "description": "Outstanding/prepaid balance in whole currency units.",
                      "type": "number"
                    },
                    "currency": {
                      "description": "ISO 4217 code all money values are expressed in.",
                      "type": "string"
                    },
                    "fundingSource": {
                      "properties": {
                        "displayString": {
                          "description": "Human-readable payment method, e.g. 'Mastercard *4985'.",
                          "type": "string"
                        },
                        "type": {
                          "description": "Meta funding source type code.",
                          "type": "integer"
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "spendCap": {
                      "description": "Account spend cap; null when none is set.",
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Account finances"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Ad account finances",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_account_finance@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "45409bdef4ec8e234dac6ca52387ce99057c21fc5a56e8a6bd6e0bf005bdc35a"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_finance",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/finance"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_finance"
      }
    },
    "/apis/v1/ads/accounts/health": {
      "get": {
        "description": "Ad Accounts. Read only. Checks whether a Meta ad account can run ads right now, with a fix link for each problem. ### What is checked the account status the payment method the account spending limit the Facebook Page and its Instagram account the Page's Lead Ads terms the newest pixel event the WhatsApp number linked to the Page\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_health",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "checkedAt": {
                      "format": "date-time",
                      "type": "string"
                    },
                    "checks": {
                      "items": {
                        "properties": {
                          "fix": {
                            "properties": {
                              "label": {
                                "type": "string"
                              },
                              "url": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "id": {
                            "enum": [
                              "account_status",
                              "payment",
                              "spend_cap",
                              "page",
                              "instagram",
                              "lead_terms",
                              "pixel",
                              "whatsapp"
                            ],
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "ok",
                              "warning",
                              "error",
                              "missing",
                              "unknown"
                            ],
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "message",
                          "status",
                          "title"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "status": {
                      "enum": [
                        "ok",
                        "attention",
                        "blocked"
                      ],
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Account checks"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Check an ad account before creating ads",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_account_health@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "c638cc5247bdce8e6a030874b52a76a7cb5ef38b55fc201e1a1142712ef0a923"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_health",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/health"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_health"
      }
    },
    "/apis/v1/ads/accounts/hierarchy": {
      "get": {
        "description": "Ad Accounts. Read only. Shows the Google Ads manager (MCC) and client account tree for a connection, including pending invitations and link status. ### How the tree is built It starts from every customer the Google user behind the connection can access directly and walks each tree to any depth with `customer_client`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_hierarchy",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Only return the tree rooted at this customer id (digits only). It must be an account the Google user accesses directly. Omit to list every tree.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for consistency with the other Google Ads account endpoints.",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "When this data was fetched from Google. Null on a live read.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "connectionId": {
                      "description": "The ads connection (adc_...) the object belongs to.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "directCustomers": {
                      "items": {
                        "properties": {
                          "customerId": {
                            "type": "string"
                          },
                          "manager": {
                            "type": "boolean"
                          },
                          "pendingInvitations": {
                            "description": "Manager invitations this account has not answered yet.",
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "roots": {
                      "items": {
                        "properties": {
                          "clients": {
                            "description": "Every account under this root at any depth, in Google's order, followed by pending invitations.",
                            "items": {
                              "additionalProperties": true,
                              "description": "A Google Ads account inside a manager tree.",
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "currency": {
                            "description": "ISO 4217 code.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "customerId": {
                            "description": "Native Google Ads customer id, digits only.",
                            "type": "string"
                          },
                          "manager": {
                            "description": "True for a manager (MCC) account.",
                            "type": "boolean"
                          },
                          "managerLinks": {
                            "description": "Managers linked to this account, ACTIVE or PENDING.",
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "description": "Google customer status: ENABLED, CANCELED, SUSPENDED or CLOSED.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "testAccount": {
                            "type": "boolean"
                          },
                          "timeZone": {
                            "description": "IANA time zone, e.g. Europe/Madrid.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when Google's quota was exhausted and this is the last successful fetch.",
                      "type": "boolean"
                    },
                    "truncated": {
                      "type": "boolean"
                    },
                    "unavailable": {
                      "items": {
                        "properties": {
                          "customerId": {
                            "type": "string"
                          },
                          "reason": {
                            "description": "Google's error message and code.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Manager and client hierarchy"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get manager account hierarchy",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_account_hierarchy@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "248b6fc5ae1d06739ca263089b62eb568407cab67866f3828e79ec80809258d7"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_hierarchy",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/hierarchy"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_hierarchy"
      }
    },
    "/apis/v1/ads/accounts/live": {
      "get": {
        "description": "Ad Accounts. Read only. Reads an ad account's campaigns and ad sets straight from Meta or TikTok, so checks like budget limits see current values. It reads one Meta ad account or TikTok advertiser live from the platform, so it is cheap enough to run before every write. For example, a per-ad-account spend ceiling that must see the current daily / lifetime budget rather than the synced copy.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_live",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_) or TikTok advertiser id (digits).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Meta `effective_status` values to keep: ACTIVE, PAUSED, IN_PROCESS, WITH_ISSUES, DELETED, ARCHIVED, and CAMPAIGN_PAUSED (ad sets only; the campaigns level ignores it). Defaults to every status except DELETED and ARCHIVED.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Read only one level. Required with `after`. Both levels are read when omitted.",
            "in": "query",
            "name": "level",
            "required": false,
            "schema": {
              "enum": [
                "campaign",
                "adSet"
              ],
              "type": "string"
            }
          },
          {
            "description": "Maximum rows per level in this response.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 200,
              "maximum": 500,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from `paging.campaigns.after` or `paging.adSets.after` of a previous response. Requires `level` (and on TikTok the same `limit`).",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "adSets": {
                      "description": "Absent when `level=campaign`.",
                      "items": {
                        "properties": {
                          "adSchedule": {
                            "description": "Meta only. The ad set's dayparting (`adset_schedule`) in the `platformSpecificData.adSchedule` shape, one window per day (a window Meta stores off the hour is widened to whole hours). Null when the ad set runs around the clock.",
                            "oneOf": [
                              {
                                "description": "Meta ad set dayparting: the hours the ad set delivers, in whole hours. Same `dayOfWeek` / `startHour` / `endHour` naming as the Google `PUT /apis/v1/ads/campaigns/{campaignId}/ad-schedule`, but Meta has no minutes and no bid modifiers.",
                                "items": {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                "maxItems": 168,
                                "type": "array"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "adSetName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "bidAmount": {
                            "description": "Bid cap or cost target in whole units of `currency` (Meta `bid_amount`; TikTok `bid_price`, else `conversion_bid_price`, else `deep_cpa_bid`). Null when the strategy has none.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "bidStrategy": {
                            "description": "Meta `bid_strategy`. On TikTok the ad group's `bid_type` normalized to the same vocabulary (LOWEST_COST_WITHOUT_CAP, LOWEST_COST_WITH_BID_CAP, LOWEST_COST_WITH_MIN_ROAS).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "billingEvent": {
                            "description": "Meta or TikTok `billing_event`.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "budget": {
                            "description": "The ad set budget, same shape as the synced rows. Null under a campaign budget.",
                            "properties": {
                              "amount": {
                                "type": "number"
                              },
                              "type": {
                                "enum": [
                                  "daily",
                                  "lifetime"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "budgetMode": {
                            "description": "TikTok only: `budget_mode` as TikTok reports it.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "budgetRemaining": {
                            "description": "Meta `budget_remaining` in whole units of `currency`. Null when the ad set has no budget of its own, and always on TikTok.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "configuredStatus": {
                            "description": "The ad set's own switch: Meta `status`, or TikTok `operation_status` as ACTIVE / PAUSED.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "dailyBudget": {
                            "description": "Daily budget in whole units of `currency`.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "lifetimeBudget": {
                            "description": "Lifetime budget in whole units of `currency`.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "optimizationGoal": {
                            "description": "Meta or TikTok `optimization_goal`.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformAdSetId": {
                            "type": "string"
                          },
                          "platformAdSetStatus": {
                            "description": "Meta `effective_status` (ACTIVE, PAUSED, CAMPAIGN_PAUSED...) or TikTok `secondary_status` (ADGROUP_STATUS_DELIVERY_OK, ADGROUP_STATUS_AUDIT...).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformCampaignId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "promotedObject": {
                            "additionalProperties": true,
                            "description": "Meta `promoted_object` verbatim (snake_case).",
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "schedule": {
                            "properties": {
                              "endDate": {
                                "description": "Absent when the ad set runs until it is stopped.",
                                "format": "date-time",
                                "type": "string"
                              },
                              "startDate": {
                                "format": "date-time",
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "status": {
                            "type": "string"
                          },
                          "targeting": {
                            "additionalProperties": true,
                            "description": "The platform's targeting verbatim (snake_case), as it reports it now: Meta `targeting`, or TikTok's ad group targeting fields (location_ids, age_groups, gender, languages, interest_category_ids, audience_ids, placements...).",
                            "type": [
                              "object",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "campaigns": {
                      "description": "Absent when `level=adSet`.",
                      "items": {
                        "properties": {
                          "bidStrategy": {
                            "description": "Meta `bid_strategy`, set on campaigns with a campaign budget. Null on TikTok.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "budget": {
                            "description": "The campaign budget, same shape as the synced rows. Null when the budget lives on the ad sets.",
                            "properties": {
                              "amount": {
                                "type": "number"
                              },
                              "type": {
                                "enum": [
                                  "daily",
                                  "lifetime"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "budgetMode": {
                            "description": "TikTok only: `budget_mode` as TikTok reports it (BUDGET_MODE_DAY, BUDGET_MODE_DYNAMIC_DAILY_BUDGET, BUDGET_MODE_TOTAL, BUDGET_MODE_INFINITE).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "budgetRemaining": {
                            "description": "Meta `budget_remaining` in whole units of `currency`. Null when the campaign has no budget of its own, and always on TikTok.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "campaignName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "configuredStatus": {
                            "description": "The campaign's own switch: Meta `status` (ACTIVE, PAUSED, DELETED, ARCHIVED), or TikTok `operation_status` as ACTIVE (ENABLE) / PAUSED (DISABLE).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "dailyBudget": {
                            "description": "Daily budget in whole units of `currency` (Meta `daily_budget`; TikTok `budget` under a daily budget mode).",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "lifetimeBudget": {
                            "description": "Lifetime budget in whole units of `currency` (Meta `lifetime_budget`; TikTok `budget` under BUDGET_MODE_TOTAL).",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "platformCampaignId": {
                            "type": "string"
                          },
                          "platformCampaignStatus": {
                            "description": "Meta `effective_status` (ACTIVE, PAUSED, WITH_ISSUES...) or TikTok `secondary_status` (CAMPAIGN_STATUS_ENABLE...).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "spendCap": {
                            "description": "Campaign spending limit (Meta `spend_cap`) in whole units of `currency`. Null when none is set, and always on TikTok.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "status": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "connectionId": {
                      "description": "The ads connection (adc_...) the object belongs to.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "currency": {
                      "description": "ISO 4217 code every budget and bid amount is expressed in.",
                      "type": "string"
                    },
                    "paging": {
                      "description": "One entry per level read. `after` is null on the last page.",
                      "properties": {
                        "adSets": {
                          "properties": {
                            "after": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "type": "object"
                        },
                        "campaigns": {
                          "properties": {
                            "after": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "type": "object"
                        }
                      },
                      "type": "object"
                    },
                    "platform": {
                      "enum": [
                        "facebook",
                        "tiktok"
                      ],
                      "type": "string"
                    },
                    "readAt": {
                      "description": "When the platform was read.",
                      "format": "date-time",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Live campaigns and ad sets"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Read an ad account's campaigns and ad sets live",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_account_live_entities@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "4a49fdf3cdfbe9d2e69261603a2d13a8bd4d066838f091dbb345d1334fecd8b2"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_live",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/live"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_live"
      }
    },
    "/apis/v1/ads/accounts/manager-links": {
      "patch": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. validateOnly=true checks the request without acting and needs no confirmation. Accepts, declines or cancels a Google Ads manager invitation, or ends an existing manager-client link. Changes one manager-client link, identified by `managerCustomerId`, `clientCustomerId` and `managerLinkId` (all from GET /apis/v1/ads/accounts/hierarchy). ### Actions `accept` and `decline`: answer a pending invitation as the client (CustomerManagerLinkService).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_accounts_manager_links",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "action": "accept",
                "clientCustomerId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "managerCustomerId": "1234567890",
                "managerLinkId": "1234567890"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "action": {
                    "enum": [
                      "accept",
                      "decline",
                      "cancel",
                      "unlink"
                    ],
                    "type": "string"
                  },
                  "clientCustomerId": {
                    "description": "Client customer id, digits only.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "managerCustomerId": {
                    "description": "Manager customer id, digits only.",
                    "type": "string"
                  },
                  "managerLinkId": {
                    "description": "Numeric link id from GET /apis/v1/ads/accounts/hierarchy.",
                    "type": "string"
                  },
                  "validateOnly": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "action",
                  "clientCustomerId",
                  "managerCustomerId",
                  "managerLinkId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "clientCustomerId": {
                      "type": "string"
                    },
                    "managerCustomerId": {
                      "type": "string"
                    },
                    "managerLinkId": {
                      "description": "Null on a validateOnly invitation, where Google creates nothing.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "status": {
                      "description": "Status the link has after this call.",
                      "enum": [
                        "PENDING",
                        "ACTIVE",
                        "REFUSED",
                        "CANCELED",
                        "INACTIVE"
                      ],
                      "type": "string"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Link updated, or validated only when validateOnly is true"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Accept, decline, cancel or end a manager link",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_account_manager_link@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e946d1e767a5acb008ddad4aca89eea3900dd1b8e16a67d03810848b0f50033f"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_accounts_manager_links",
          "method": "PATCH",
          "path": "/apis/v1/ads/accounts/manager-links"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_accounts_manager_links"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. validateOnly=true checks the request without acting and needs no confirmation. Invites a Google Ads account to be managed by one of your manager accounts; the link stays pending until the client accepts. Sends a manager-to-client link invitation from `managerCustomerId` to `clientCustomerId` (Google's CustomerClientLinkService). The manager must be one the connection's Google user reaches, directly or under another manager (see GET /apis/v1/ads/accounts/hierarchy).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_accounts_manager_links",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "clientCustomerId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "managerCustomerId": "1234567890"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "clientCustomerId": {
                    "description": "Client customer id to invite, digits only.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "managerCustomerId": {
                    "description": "Manager customer id, digits only.",
                    "type": "string"
                  },
                  "validateOnly": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "clientCustomerId",
                  "managerCustomerId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "clientCustomerId": {
                      "type": "string"
                    },
                    "managerCustomerId": {
                      "type": "string"
                    },
                    "managerLinkId": {
                      "description": "Null on a validateOnly invitation, where Google creates nothing.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "status": {
                      "description": "Status the link has after this call.",
                      "enum": [
                        "PENDING",
                        "ACTIVE",
                        "REFUSED",
                        "CANCELED",
                        "INACTIVE"
                      ],
                      "type": "string"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Validated only (validateOnly true), nothing sent"
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "clientCustomerId": {
                      "type": "string"
                    },
                    "managerCustomerId": {
                      "type": "string"
                    },
                    "managerLinkId": {
                      "description": "Null on a validateOnly invitation, where Google creates nothing.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "status": {
                      "description": "Status the link has after this call.",
                      "enum": [
                        "PENDING",
                        "ACTIVE",
                        "REFUSED",
                        "CANCELED",
                        "INACTIVE"
                      ],
                      "type": "string"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Invitation sent"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Invite a client account to a manager",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.invite_ad_account_to_manager@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "5dd1a717fdfe7fcb46b38e2dbea32b71cb5878bbf0aba5f1251437ac2a4ffd92"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_accounts_manager_links",
          "method": "POST",
          "path": "/apis/v1/ads/accounts/manager-links"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_accounts_manager_links"
      }
    },
    "/apis/v1/ads/accounts/negative-keyword-lists": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the shared negative keyword lists in a Google Ads account, which you can apply to many campaigns at once. Google Ads shared negative keyword lists (shared_set type NEGATIVE_KEYWORDS). Reads are cached for 10 minutes; quota exhaustion may return the last successful result for up to 7 days with stale=true. Customer selection is limited to this connection and its account scope.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_negative_keyword_lists",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "description": "Alias of adAccountId, kept for existing callers",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "description": "Optional courtesy field. The resolved account or campaign determines support; other platforms return 501.",
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "meta",
                "x"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "Last successful fetch time, or null without cache storage.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "description": "Resolved Google Ads customer id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "lists": {
                      "items": {
                        "properties": {
                          "id": {
                            "description": "Google shared set id.",
                            "pattern": "^\\d+$",
                            "type": "string"
                          },
                          "memberCount": {
                            "description": "Number of keywords in the list.",
                            "type": "integer"
                          },
                          "name": {
                            "description": "List name.",
                            "type": "string"
                          },
                          "referenceCount": {
                            "description": "Number of resources referencing the list.",
                            "type": "integer"
                          },
                          "resourceName": {
                            "description": "Google shared set resource name.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when quota exhaustion caused the last successful cached result to be served.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Successful response."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List negative keyword lists",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_negative_keyword_lists@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "8e1fa194cda43fde3ebb8c0e3480f07d2afb42133b78517fcd2720e0006c99b4"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_negative_keyword_lists",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/negative-keyword-lists"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_negative_keyword_lists"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Creates a shared Google Ads negative keyword list, optionally with starting keywords; it is not attached to any campaign yet. Creates one Google Ads shared negative keyword list with optional initial keywords in a single atomic mutation. Daily quota is reserved for every mutate item, so large batches may return 429 before any change. This operation is not idempotent.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_accounts_negative_keywo_5c3c7f",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "9122445560",
                "connectionId": "adc_7f3k2m9q",
                "keywords": [
                  "free",
                  {
                    "matchType": "phrase",
                    "text": "jobs"
                  }
                ],
                "name": "Excluded searches"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "keywords": {
                    "description": "Full desired keyword set. Bare strings use broad match. Send [] to clear the list.",
                    "items": {
                      "description": "A Google Search keyword: a bare string (BROAD match), or an object naming the match type.",
                      "oneOf": [
                        {
                          "description": "Keyword text; defaults to BROAD match",
                          "maxLength": 80,
                          "minLength": 1,
                          "type": "string"
                        },
                        {
                          "properties": {
                            "matchType": {
                              "description": "Defaults to broad. Accepted in any case (EXACT, Exact) and stored lowercase.",
                              "enum": [
                                "exact",
                                "phrase",
                                "broad"
                              ],
                              "type": "string"
                            },
                            "text": {
                              "maxLength": 80,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "maxItems": 5000,
                    "type": "array"
                  },
                  "name": {
                    "description": "Nonempty list name, trimmed before use.",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "platform": {
                    "description": "Optional courtesy field. The resolved account or campaign determines support; other platforms return 501. Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "created": {
                      "description": "Number of initial keyword criteria created.",
                      "type": "integer"
                    },
                    "customerId": {
                      "description": "Resolved Google Ads customer id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "id": {
                      "description": "New shared set id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "resourceName": {
                      "description": "New shared set resource name.",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Successful response."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a negative keyword list",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_negative_keyword_list@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "dd5c4ef842f795ff5de70873d1dbac8382dbf221f2a8d4395d06e6c92e151a5a"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_accounts_negative_keywo_5c3c7f",
          "method": "POST",
          "path": "/apis/v1/ads/accounts/negative-keyword-lists"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_accounts_negative_keywo_5c3c7f"
      }
    },
    "/apis/v1/ads/accounts/negative-keyword-lists/{listId}": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Deletes a shared Google Ads negative keyword list; detach it from every campaign first. Detach it from all campaigns first; an in-use list is rejected. Only NEGATIVE_KEYWORDS shared sets are supported.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_accounts_negative_key_295d71",
        "parameters": [
          {
            "in": "path",
            "name": "listId",
            "required": true,
            "schema": {
              "description": "Google shared set id.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "description": "Alias of adAccountId, kept for existing callers",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "description": "Optional courtesy field. The resolved account or campaign determines support; other platforms return 501.",
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "meta",
                "x"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "description": "Resolved Google Ads customer id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "removed": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Successful response."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete a negative keyword list",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_negative_keyword_list@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "d105e350931ed7dfa8fe4d9ac95c64b8788571fc1b74b78ccf8428ba3df1cfbf"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_accounts_negative_key_295d71",
          "method": "DELETE",
          "path": "/apis/v1/ads/accounts/negative-keyword-lists/{listId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_accounts_negative_key_295d71"
      },
      "get": {
        "description": "Ad Accounts. Read only. Shows one shared Google Ads negative keyword list with all of its keywords. Google Ads shared negative keyword lists (shared_set type NEGATIVE_KEYWORDS). Reads are cached for 10 minutes; quota exhaustion may return the last successful result for up to 7 days with stale=true. Customer selection is limited to this connection and its account scope. Includes the keywords and their criterion ids.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_negative_keywor_295d71",
        "parameters": [
          {
            "in": "path",
            "name": "listId",
            "required": true,
            "schema": {
              "description": "Google shared set id.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "description": "Alias of adAccountId, kept for existing callers",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "description": "Optional courtesy field. The resolved account or campaign determines support; other platforms return 501.",
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "meta",
                "x"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "Last successful fetch time, or null without cache storage.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "description": "Resolved Google Ads customer id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "list": {
                      "properties": {
                        "id": {
                          "description": "Google shared set id.",
                          "pattern": "^\\d+$",
                          "type": "string"
                        },
                        "keywords": {
                          "items": {
                            "properties": {
                              "criterionId": {
                                "description": "Google shared criterion id.",
                                "pattern": "^\\d+$",
                                "type": "string"
                              },
                              "matchType": {
                                "enum": [
                                  "broad",
                                  "phrase",
                                  "exact"
                                ],
                                "type": "string"
                              },
                              "text": {
                                "description": "Keyword text.",
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "memberCount": {
                          "description": "Number of keywords in the list.",
                          "type": "integer"
                        },
                        "name": {
                          "description": "List name.",
                          "type": "string"
                        },
                        "referenceCount": {
                          "description": "Number of resources referencing the list.",
                          "type": "integer"
                        },
                        "resourceName": {
                          "description": "Google shared set resource name.",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "stale": {
                      "description": "True when quota exhaustion caused the last successful cached result to be served.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Successful response."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get a negative keyword list",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_negative_keyword_list@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6e2324207fd6ad9324862577441635c583dd7f5fb66c58987e082bcaffce5f94"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_negative_keywor_295d71",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/negative-keyword-lists/{listId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_negative_keywor_295d71"
      },
      "put": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Renames a shared Google Ads negative keyword list without changing its keywords or the campaigns using it. Keywords and campaign associations are unchanged. Use the keywords endpoint to edit the desired keyword set.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_accounts_negative_keywor_295d71",
        "parameters": [
          {
            "in": "path",
            "name": "listId",
            "required": true,
            "schema": {
              "description": "Google shared set id.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "9122445560",
                "connectionId": "adc_7f3k2m9q",
                "name": "Excluded searches renamed"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "name": {
                    "description": "Nonempty list name, trimmed before use.",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "platform": {
                    "description": "Optional courtesy field. The resolved account or campaign determines support; other platforms return 501. Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "description": "Resolved Google Ads customer id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "updated": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Successful response."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Rename a negative keyword list",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_negative_keyword_list@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a3072cf08daa588a1f56f589a9b6790322dd8dcfb12ccd5c7d7e6db0185f6ae0"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_accounts_negative_keywor_295d71",
          "method": "PUT",
          "path": "/apis/v1/ads/accounts/negative-keyword-lists/{listId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_accounts_negative_keywor_295d71"
      }
    },
    "/apis/v1/ads/accounts/negative-keyword-lists/{listId}/keywords": {
      "put": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Replaces all keywords in a shared Google Ads negative keyword list (or clears it), affecting every campaign that uses the list. Existing keywords are diffed by normalized text and match type. Creates and removals are applied atomically in one mutation. Unchanged criteria retain their ids. Send an empty keywords array to clear the list. Changes affect every campaign using this list. ### Quota\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_accounts_negative_keywor_8bdebe",
        "parameters": [
          {
            "in": "path",
            "name": "listId",
            "required": true,
            "schema": {
              "description": "Google shared set id.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "9122445560",
                "connectionId": "adc_7f3k2m9q",
                "keywords": [
                  "free",
                  {
                    "matchType": "phrase",
                    "text": "jobs"
                  }
                ]
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "keywords": {
                    "description": "Full desired keyword set. Bare strings use broad match. Send [] to clear the list.",
                    "items": {
                      "description": "A Google Search keyword: a bare string (BROAD match), or an object naming the match type.",
                      "oneOf": [
                        {
                          "description": "Keyword text; defaults to BROAD match",
                          "maxLength": 80,
                          "minLength": 1,
                          "type": "string"
                        },
                        {
                          "properties": {
                            "matchType": {
                              "description": "Defaults to broad. Accepted in any case (EXACT, Exact) and stored lowercase.",
                              "enum": [
                                "exact",
                                "phrase",
                                "broad"
                              ],
                              "type": "string"
                            },
                            "text": {
                              "maxLength": 80,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "maxItems": 5000,
                    "type": "array"
                  },
                  "platform": {
                    "description": "Optional courtesy field. The resolved account or campaign determines support; other platforms return 501. Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "keywords"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "created": {
                      "description": "New criteria or campaign links created.",
                      "type": "integer"
                    },
                    "customerId": {
                      "description": "Resolved Google Ads customer id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "removed": {
                      "description": "Existing criteria or campaign links removed.",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Successful response."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Replace negative list keywords",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.replace_ad_negative_keyword_list_keywords@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "9c5c5e66d06e78478544305d3519bc322960caafc50699c15ad8f0de2e638544"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_accounts_negative_keywor_8bdebe",
          "method": "PUT",
          "path": "/apis/v1/ads/accounts/negative-keyword-lists/{listId}/keywords"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_accounts_negative_keywor_8bdebe"
      }
    },
    "/apis/v1/ads/accounts/sitelinks": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Detaches a sitelink from the Google Ads account level, leaving it on any campaigns or ad groups that still use it. Removes the customer_asset attachment only. The underlying shared asset and its campaign or ad-group attachments remain. Fields go in the query string. A JSON body with the same fields is also accepted and, when sent, the query string is ignored.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_accounts_sitelinks",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Numeric Google Ads asset id.",
            "in": "query",
            "name": "assetId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "removed": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove account sitelink",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_account_sitelink@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "38451d43d9d7dfdd421f4907435993fa45cf131af6fa4fa72b43d1d845d41815"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_accounts_sitelinks",
          "method": "DELETE",
          "path": "/apis/v1/ads/accounts/sitelinks"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_accounts_sitelinks"
      },
      "get": {
        "description": "Ad Accounts. Read only. Lists the sitelinks attached at account level in Google Ads, which can show on ads across all campaigns. Fresh reads are cached for 10 minutes; exhausted quota may return the last successful read with stale=true. Inherited assets are not included.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_sitelinks",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "description": "Alias of adAccountId, kept for existing callers",
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "Time of the cached Google read. Null when no cache was used.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "sitelinks": {
                      "items": {
                        "properties": {
                          "assetId": {
                            "type": "string"
                          },
                          "assetResourceName": {
                            "type": "string"
                          },
                          "customerAssetResourceName": {
                            "type": "string"
                          },
                          "description1": {
                            "type": "string"
                          },
                          "description2": {
                            "type": "string"
                          },
                          "linkUrl": {
                            "format": "uri",
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "text": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when exhausted quota required returning the last successful read.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List account sitelinks",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_account_sitelinks@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "be67e88720a24e037325ad1d2e42e2b71b355883cc4dfb0ba4cc45776e5775ea"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_sitelinks",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/sitelinks"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_sitelinks"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Creates sitelinks and attaches them at account level in Google Ads so they can show on ads across all campaigns. Creates assets and customer_asset links for this Google customer. Links apply at account level.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_accounts_sitelinks",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "sitelinks": [
                  {
                    "linkUrl": "https://example.com/landing",
                    "text": "Pricing"
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "sitelinks": {
                    "items": {
                      "properties": {
                        "description1": {
                          "maxLength": 35,
                          "minLength": 1,
                          "type": "string"
                        },
                        "description2": {
                          "maxLength": 35,
                          "minLength": 1,
                          "type": "string"
                        },
                        "linkUrl": {
                          "format": "uri",
                          "type": "string"
                        },
                        "text": {
                          "maxLength": 25,
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "linkUrl",
                        "text"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "sitelinks"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "sitelinks": {
                      "items": {
                        "properties": {
                          "assetId": {
                            "type": "string"
                          },
                          "description1": {
                            "maxLength": 35,
                            "minLength": 1,
                            "type": "string"
                          },
                          "description2": {
                            "maxLength": 35,
                            "minLength": 1,
                            "type": "string"
                          },
                          "linkUrl": {
                            "format": "uri",
                            "type": "string"
                          },
                          "text": {
                            "maxLength": 25,
                            "minLength": 1,
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets created and attached."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Add account sitelinks",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.add_account_sitelinks@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "fab9645933c9984d877d252f664b8e6e58c14ce6668a1c42fff2479015105b91"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_accounts_sitelinks",
          "method": "POST",
          "path": "/apis/v1/ads/accounts/sitelinks"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_accounts_sitelinks"
      },
      "put": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Edits existing Google Ads sitelinks in place; the change applies everywhere that sitelink is used. Send updates with assetResourceName and the fields to change. An asset is shared: changes affect every attachment using it. Omitted fields stay unchanged. The operation consumes the Google operations budget and invalidates affected cached lists.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_accounts_sitelinks",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "updates": [
                  {
                    "assetResourceName": "customers/1234567890/assets/123",
                    "finalUrls": [
                      "https://example.com/landing"
                    ],
                    "sitelinkAsset": {
                      "linkText": "Explore pricing"
                    }
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "updates": {
                    "items": {
                      "description": "Provide at least one field belonging to this asset type.",
                      "properties": {
                        "assetResourceName": {
                          "description": "Asset resource name returned by a list operation. Must belong to the selected customer.",
                          "pattern": "^customers/\\d+/assets/\\d+$",
                          "type": "string"
                        },
                        "finalUrls": {
                          "items": {
                            "format": "uri",
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "sitelinkAsset": {
                          "properties": {
                            "description1": {
                              "maxLength": 35,
                              "type": "string"
                            },
                            "description2": {
                              "maxLength": 35,
                              "type": "string"
                            },
                            "linkText": {
                              "maxLength": 25,
                              "minLength": 1,
                              "type": "string"
                            },
                            "linkUrl": {
                              "description": "Alias for finalUrls with one URL. Do not supply both.",
                              "format": "uri",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        }
                      },
                      "required": [
                        "assetResourceName"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "updates"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "updated": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update account sitelinks",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_account_sitelinks@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "615eb7e19667e2478695c8fc6e43701eb0e028b2ac30b76ad93099e930cd51b4"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_accounts_sitelinks",
          "method": "PUT",
          "path": "/apis/v1/ads/accounts/sitelinks"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_accounts_sitelinks"
      }
    },
    "/apis/v1/ads/accounts/structured-snippets": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Detaches a structured snippet from the Google Ads account level, leaving it on any campaigns or ad groups that still use it. Removes the customer_asset attachment only. The underlying shared asset and its campaign or ad-group attachments remain. Fields go in the query string. A JSON body with the same fields is also accepted and, when sent, the query string is ignored.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_accounts_structured_snippets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Numeric Google Ads asset id.",
            "in": "query",
            "name": "assetId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "removed": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove account snippet",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_account_structured_snippet@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "79203446ad24f433775931c41e799c0133c5641d2bf06c554722acbc0c5553af"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_accounts_structured_snippets",
          "method": "DELETE",
          "path": "/apis/v1/ads/accounts/structured-snippets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_accounts_structured_snippets"
      },
      "get": {
        "description": "Ad Accounts. Read only. Lists the structured snippets attached at account level in Google Ads, which can show on ads across all campaigns. Fresh reads are cached for 10 minutes; exhausted quota may return the last successful read with stale=true. Inherited assets are not included.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_structured_snippets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "description": "Alias of adAccountId, kept for existing callers",
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "Time of the cached Google read. Null when no cache was used.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "stale": {
                      "description": "True when exhausted quota required returning the last successful read.",
                      "type": "boolean"
                    },
                    "structuredSnippets": {
                      "items": {
                        "properties": {
                          "assetId": {
                            "type": "string"
                          },
                          "assetResourceName": {
                            "type": "string"
                          },
                          "customerAssetResourceName": {
                            "type": "string"
                          },
                          "header": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "values": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List account snippets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_account_structured_snippets@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e25205e93bf6f081ed102b2ca135b7fc47e4f45c529acf354af0ad58a2eb36e5"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_structured_snippets",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/structured-snippets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_structured_snippets"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Creates structured snippets and attaches them at account level in Google Ads so they can show on ads across all campaigns. Creates assets and customer_asset links for this Google customer. Links apply at account level.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_accounts_structured_snippets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "structuredSnippets": [
                  {
                    "header": "Types",
                    "values": [
                      "Scheduling",
                      "Analytics",
                      "Messaging"
                    ]
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "structuredSnippets": {
                    "items": {
                      "properties": {
                        "header": {
                          "enum": [
                            "Amenities",
                            "Brands",
                            "Courses",
                            "Degree programs",
                            "Destinations",
                            "Featured hotels",
                            "Insurance coverage",
                            "Models",
                            "Neighborhoods",
                            "Service catalog",
                            "Shows",
                            "Styles",
                            "Types"
                          ],
                          "type": "string"
                        },
                        "values": {
                          "items": {
                            "maxLength": 25,
                            "minLength": 1,
                            "type": "string"
                          },
                          "maxItems": 10,
                          "minItems": 3,
                          "type": "array"
                        }
                      },
                      "required": [
                        "header",
                        "values"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "structuredSnippets"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "structuredSnippets": {
                      "items": {
                        "properties": {
                          "assetId": {
                            "type": "string"
                          },
                          "header": {
                            "enum": [
                              "Amenities",
                              "Brands",
                              "Courses",
                              "Degree programs",
                              "Destinations",
                              "Featured hotels",
                              "Insurance coverage",
                              "Models",
                              "Neighborhoods",
                              "Service catalog",
                              "Shows",
                              "Styles",
                              "Types"
                            ],
                            "type": "string"
                          },
                          "values": {
                            "items": {
                              "maxLength": 25,
                              "minLength": 1,
                              "type": "string"
                            },
                            "maxItems": 10,
                            "minItems": 3,
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets created and attached."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Add account snippets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.add_account_structured_snippets@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "94ded41169a4149c456261dcdad241be8e907c674bb7be4f42b4550643fe1140"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_accounts_structured_snippets",
          "method": "POST",
          "path": "/apis/v1/ads/accounts/structured-snippets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_accounts_structured_snippets"
      },
      "put": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Edits existing Google Ads structured snippets in place; the change applies everywhere that snippet is used. Send updates with assetResourceName and the fields to change. An asset is shared: changes affect every attachment using it. Omitted fields stay unchanged. The operation consumes the Google operations budget and invalidates affected cached lists.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_accounts_structured_snippets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "updates": [
                  {
                    "assetResourceName": "customers/1234567890/assets/123",
                    "structuredSnippetAsset": {
                      "header": "Types",
                      "values": [
                        "Scheduling",
                        "Reporting",
                        "Messaging"
                      ]
                    }
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "updates": {
                    "items": {
                      "description": "Provide at least one field belonging to this asset type.",
                      "properties": {
                        "assetResourceName": {
                          "description": "Asset resource name returned by a list operation. Must belong to the selected customer.",
                          "pattern": "^customers/\\d+/assets/\\d+$",
                          "type": "string"
                        },
                        "structuredSnippetAsset": {
                          "properties": {
                            "header": {
                              "enum": [
                                "Amenities",
                                "Brands",
                                "Courses",
                                "Degree programs",
                                "Destinations",
                                "Featured hotels",
                                "Insurance coverage",
                                "Models",
                                "Neighborhoods",
                                "Service catalog",
                                "Shows",
                                "Styles",
                                "Types"
                              ],
                              "type": "string"
                            },
                            "values": {
                              "items": {
                                "maxLength": 25,
                                "minLength": 1,
                                "type": "string"
                              },
                              "maxItems": 10,
                              "minItems": 3,
                              "type": "array"
                            }
                          },
                          "required": [
                            "header",
                            "values"
                          ],
                          "type": "object"
                        }
                      },
                      "required": [
                        "assetResourceName"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "updates"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "updated": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update account snippets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_account_structured_snippets@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a10c64afc22f419264666852180e9d90c0778f88edacb4f1fe1c68a4714214c9"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_accounts_structured_snippets",
          "method": "PUT",
          "path": "/apis/v1/ads/accounts/structured-snippets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_accounts_structured_snippets"
      }
    },
    "/apis/v1/ads/accounts/user-invitations": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Withdraws an email invitation to a Google Ads account that has not been accepted yet. Removes the invitation `invitationId` (from GET on this path) from `adAccountId`. It no longer works from the email, and the address can be invited again.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_accounts_user_invitations",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google Ads customer id, digits only.",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Numeric invitation id from GET /apis/v1/ads/accounts/user-invitations.",
            "in": "query",
            "name": "invitationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "invitationId": {
                      "type": "string"
                    },
                    "revoked": {
                      "description": "Always true.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Invitation revoked"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Revoke a user access invitation",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.revoke_ad_account_user_invitation@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "75225b0a675892c7cb6809bb0bded451b17d353a77399aabe9885741c3f618b1"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_accounts_user_invitations",
          "method": "DELETE",
          "path": "/apis/v1/ads/accounts/user-invitations"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_accounts_user_invitations"
      },
      "get": {
        "description": "Ad Accounts. Read only. Lists the email invitations to a Google Ads account, with their role and status. Reads Google's `customer_user_access_invitation` resource for one customer. Listed invitations are: `PENDING` `DECLINED` `EXPIRED` (Google expires them 20 days after sending) ### Not listed An accepted invitation becomes a user of the account and leaves this list, which can take Google up to 24 hours.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_user_invitations",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google Ads customer id, digits only. Defaults to the connection's selected customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "When this data was fetched from Google. Null when the cache is unavailable.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "invitations": {
                      "items": {
                        "properties": {
                          "accessRole": {
                            "enum": [
                              "ADMIN",
                              "STANDARD",
                              "READ_ONLY",
                              "EMAIL_ONLY",
                              "UNKNOWN"
                            ],
                            "type": "string"
                          },
                          "createdAt": {
                            "description": "Google's creation time, yyyy-MM-dd HH:mm:ss.ssssss in the account's time zone.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "emailAddress": {
                            "type": "string"
                          },
                          "invitationId": {
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "PENDING",
                              "DECLINED",
                              "EXPIRED",
                              "UNKNOWN"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when Google's quota was exhausted and this is the last successful fetch.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Invitations of the customer"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List user access invitations",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_account_user_invitations@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "5ce20baf8720b4b9cb62518d1584712e0d6e0c991e52ead0c26376dba56370e0"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_user_invitations",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/user-invitations"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_user_invitations"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. validateOnly=true checks the request without acting and needs no confirmation. Emails someone an invitation to a Google Ads account with the access role you choose, for example to hand a client account you created under your manager to its owner. It creates a user access invitation (Google's CustomerUserAccessInvitationService) on `adAccountId`. The recipient accepts from the email, possibly with another Google account. ### Access needed\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_accounts_user_invitations",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "accessRole": "ADMIN",
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "emailAddress": "example"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "accessRole": {
                    "description": "ADMIN manages the account and its users, STANDARD edits campaigns, READ_ONLY views them, EMAIL_ONLY only receives the account's emails.",
                    "enum": [
                      "ADMIN",
                      "STANDARD",
                      "READ_ONLY",
                      "EMAIL_ONLY"
                    ],
                    "type": "string"
                  },
                  "adAccountId": {
                    "description": "Google Ads customer id to invite the user to, digits only.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "emailAddress": {
                    "format": "email",
                    "type": "string"
                  },
                  "validateOnly": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "accessRole",
                  "adAccountId",
                  "emailAddress"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "accessRole": {
                      "description": "ADMIN manages the account and its users, STANDARD edits campaigns, READ_ONLY views them, EMAIL_ONLY only receives the account's emails.",
                      "enum": [
                        "ADMIN",
                        "STANDARD",
                        "READ_ONLY",
                        "EMAIL_ONLY"
                      ],
                      "type": "string"
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "emailAddress": {
                      "type": "string"
                    },
                    "invitationId": {
                      "description": "Null on validateOnly and while the invitation awaits multi-party approval.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "multiPartyAuthReviewId": {
                      "description": "Google's multi-party approval review id when status is PENDING_APPROVAL.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "status": {
                      "description": "PENDING once the email is sent; PENDING_APPROVAL while Google waits for a second admin's multi-party approval.",
                      "enum": [
                        "PENDING",
                        "PENDING_APPROVAL"
                      ],
                      "type": "string"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Validated only (validateOnly true), nothing sent"
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "accessRole": {
                      "description": "ADMIN manages the account and its users, STANDARD edits campaigns, READ_ONLY views them, EMAIL_ONLY only receives the account's emails.",
                      "enum": [
                        "ADMIN",
                        "STANDARD",
                        "READ_ONLY",
                        "EMAIL_ONLY"
                      ],
                      "type": "string"
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "emailAddress": {
                      "type": "string"
                    },
                    "invitationId": {
                      "description": "Null on validateOnly and while the invitation awaits multi-party approval.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "multiPartyAuthReviewId": {
                      "description": "Google's multi-party approval review id when status is PENDING_APPROVAL.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "status": {
                      "description": "PENDING once the email is sent; PENDING_APPROVAL while Google waits for a second admin's multi-party approval.",
                      "enum": [
                        "PENDING",
                        "PENDING_APPROVAL"
                      ],
                      "type": "string"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Invitation sent, or held for multi-party approval"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Invite a user to an ad account by email",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.invite_ad_account_user@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a7118d865d7f0d822c0e931abadf9e9a24aa167b9b73290be9829e3d62070bc8"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_accounts_user_invitations",
          "method": "POST",
          "path": "/apis/v1/ads/accounts/user-invitations"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_accounts_user_invitations"
      }
    },
    "/apis/v1/ads/accounts/user-invitations/pending-approvals": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Cancels an email invitation that Google is still holding for a second admin's approval, so the same address can be invited again right away. It resolves the review `multiPartyAuthReviewId` (from POST /apis/v1/ads/accounts/user-invitations or GET on this path) to `REVOKED` through Google's MultiPartyAuthReviewService.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_accounts_user_invitat_1d6fed",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google Ads customer id, digits only.",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Numeric review id from POST /apis/v1/ads/accounts/user-invitations or GET /apis/v1/ads/accounts/user-invitations/pending-approvals.",
            "in": "query",
            "name": "multiPartyAuthReviewId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "multiPartyAuthReviewId": {
                      "type": "string"
                    },
                    "status": {
                      "enum": [
                        "REVOKED"
                      ],
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Approval request withdrawn"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Withdraw an invitation awaiting multi-party approval",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.withdraw_ad_account_user_invitation_approval@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "b8eb534a7fca4f36a921da49effa67f80993f8bd397d9406bf5f818c0e4758c3"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_accounts_user_invitat_1d6fed",
          "method": "DELETE",
          "path": "/apis/v1/ads/accounts/user-invitations/pending-approvals"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_accounts_user_invitat_1d6fed"
      },
      "get": {
        "description": "Ad Accounts. Read only. Lists the email invitations to a Google Ads account that Google is holding until a second admin approves them. When Google requires multi-party approval, POST /apis/v1/ads/accounts/user-invitations answers `status: PENDING_APPROVAL` and sends nothing. Those requests are not in GET /apis/v1/ads/accounts/user-invitations.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_user_invitation_1d6fed",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google Ads customer id, digits only. Defaults to the connection's selected customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "approvals": {
                      "items": {
                        "properties": {
                          "accessRole": {
                            "enum": [
                              "ADMIN",
                              "STANDARD",
                              "READ_ONLY",
                              "EMAIL_ONLY",
                              "UNKNOWN"
                            ],
                            "type": "string"
                          },
                          "createdAt": {
                            "description": "Google's creation time, yyyy-MM-dd HH:mm:ss.ssssss in the account's time zone.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "emailAddress": {
                            "description": "Invited email address.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "multiPartyAuthReviewId": {
                            "description": "Pass to DELETE /apis/v1/ads/accounts/user-invitations/pending-approvals to withdraw the request.",
                            "type": "string"
                          },
                          "requestUserEmail": {
                            "description": "Google user who sent the invitation. Only this user can withdraw it.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "cachedAt": {
                      "description": "When this data was fetched from Google. Null when the cache is unavailable.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "stale": {
                      "description": "True when Google's quota was exhausted and this is the last successful fetch.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Invitations awaiting approval on the customer"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List invitations awaiting multi-party approval",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_account_user_invitation_approvals@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "32a15221bc4f99737ce44c4c4c4e738bf87c61d2af1811f50af304da819570bd"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_user_invitation_1d6fed",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/user-invitations/pending-approvals"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_user_invitation_1d6fed"
      }
    },
    "/apis/v1/ads/accounts/users": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Removes a person's access to a Meta ad account assigned through your business portfolio.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_accounts_users",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Business-scoped user id.",
            "in": "query",
            "name": "userId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "removed": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "User removed"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove a user from an ad account",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_ad_account_user@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "3a7a4594a3d8037f7c384fc47838312c96f513fda0273aa27b1871ac67919df7"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_accounts_users",
          "method": "DELETE",
          "path": "/apis/v1/ads/accounts/users"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_accounts_users"
      },
      "get": {
        "description": "Ad Accounts. Read only. Lists the people in a business portfolio assigned to a Meta ad account, with what each can do. Ids are business-scoped user ids (see `GET /apis/v1/ads/businesses/users`).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_accounts_users",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Business portfolio whose people to list.",
            "in": "query",
            "name": "businessId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "businessId": {
                      "type": "string"
                    },
                    "users": {
                      "items": {
                        "properties": {
                          "id": {
                            "description": "Business-scoped user id.",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "tasks": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assigned users"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Ad account users",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_account_users@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "c122cacba44770c5c9d52ff6356680eb1b8a6c6f15784ed8f56db94d6cea82b8"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_accounts_users",
          "method": "GET",
          "path": "/apis/v1/ads/accounts/users"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_accounts_users"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Gives a person in your business portfolio access to a Meta ad account, as admin, advertiser, analyst or draft editor. `MANAGE` is admin, `ADVERTISE` creates and edits ads, `ANALYZE` reads reports, `DRAFT` edits drafts only. Assigning an already assigned user replaces their task set.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_accounts_users",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_123456789",
                "connectionId": "adc_7f3k2m9q",
                "tasks": [
                  "ADVERTISE",
                  "ANALYZE"
                ],
                "userId": "1122334455"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Meta ad account id (act_).",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "tasks": {
                    "items": {
                      "enum": [
                        "MANAGE",
                        "ADVERTISE",
                        "ANALYZE",
                        "DRAFT"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "userId": {
                    "description": "Business-scoped user id from GET /apis/v1/ads/businesses/users.",
                    "type": "string"
                  }
                },
                "required": [
                  "adAccountId",
                  "tasks",
                  "userId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "user": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "tasks": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "User assigned"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Assign a user to an ad account",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.assign_ad_account_user@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1a77ae2ae6ef4a8003e99abde03bb20be717e669610b224cdd3e1d4044ddcbd4"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_accounts_users",
          "method": "POST",
          "path": "/apis/v1/ads/accounts/users"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_accounts_users"
      }
    },
    "/apis/v1/ads/activity": {
      "get": {
        "description": "Ad Accounts. Read only. Shows who changed what in an ad account and when, as an audit log of edits to campaigns, ad sets and ads. ### Google Reads the customer's `change_event` history, newest first. `adAccountId` is the numeric customer id. Google keeps 30 days of it, so `since` defaults to 29 days ago and an older `since` returns 400. `until` defaults to today. Each change is mapped onto the Meta row shape:\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_activity",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_), or the Google customer id (digits only).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start of range (YYYY-MM-DD). Google: at most 29 days ago, the default.",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End of range (YYYY-MM-DD).",
            "in": "query",
            "name": "until",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Client-side filter to one object id (campaign, ad set / ad group or ad). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "objectId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Rows per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 200,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "description": "Raw Meta activity row: event_type, translated_event_type, event_time, actor_name, object_id, object_name, object_type, application_name, extra_data (JSON string with before/after).",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Activity rows (raw Meta shape; Google changes mapped onto it)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Ad account change / audit log",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ads_activity_log@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a1fda75228b44244a89e2217f65dadbc39d767efbcb37c06610b5e24273f66e6"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_activity",
          "method": "GET",
          "path": "/apis/v1/ads/activity"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_activity"
      }
    },
    "/apis/v1/ads/ad-sets": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists ad sets (ad groups on Google) with their targeting, bidding and optimization settings, optionally for one campaign. Returns the ad sets (Google ad groups) synced for the connection, optionally filtered by platform and campaignId. It reads the `ad_sets` table directly, independent of the `ads` rollup GET /apis/v1/ads/tree uses.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_ad_sets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account id (Meta act_). Lists every synced ad set of that ad account; no campaignId needed.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Platform campaign ID Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Platform ad set ID Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "adSetId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "meta",
                "x"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter by the ad set's stored `status`, the value each row returns. A live read does not change it. Rows whose `status` is null match no filter.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "active",
                "paused",
                "pending_review",
                "rejected",
                "completed",
                "cancelled",
                "error"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 500,
              "maximum": 500,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Read the on/off switches live from the platform instead of returning synced values. See \"Status freshness\" in the operation description.",
            "in": "query",
            "name": "live",
            "required": false,
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adSets": {
                      "items": {
                        "properties": {
                          "adSetName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "bidAmount": {
                            "description": "Bid cap or cost target in whole units of `currency`, as last synced. Null when the strategy has none (automatic bidding, ROAS targets, a Google portfolio strategy).",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "bidStrategy": {
                            "description": "The bid strategy as last synced, in Meta's vocabulary (LOWEST_COST_WITHOUT_CAP, LOWEST_COST_WITH_BID_CAP, COST_CAP, LOWEST_COST_WITH_MIN_ROAS) on every platform that has an equivalent.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "billingEvent": {
                            "description": "The ad set's billing event as last synced, in the platform's own enum: Meta `billing_event`, TikTok `billing_event`, Pinterest `billable_event`, X `pay_by`, OpenAI `bidding_config.billing_event_type`.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "budget": {
                            "properties": {
                              "amount": {
                                "type": "number"
                              },
                              "daily": {
                                "description": "LinkedIn and X only. The daily budget (LinkedIn: the campaign's `dailyBudget`; X: the line item's `daily_budget_amount_local_micro`).",
                                "type": "number"
                              },
                              "lifetime": {
                                "description": "LinkedIn and X only. The lifetime total (LinkedIn: the campaign's `totalBudget`; X: the line item's `total_budget_amount_local_micro`), readable even when a daily budget is also set.",
                                "type": "number"
                              },
                              "pacing": {
                                "description": "LinkedIn only. The campaign's `pacingStrategy`: how fast LinkedIn may spend the budget. Typically LINEAR or ACCELERATED; the list is open.",
                                "type": "string"
                              },
                              "type": {
                                "enum": [
                                  "daily",
                                  "lifetime"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "configReadAt": {
                            "description": "Only with `live=true`. When `nativeSettings` was read from the platform. Null on every row whose native settings were not read now (row past the cap, failed read, or a platform without a native read).",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "currency": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "isExternal": {
                            "type": [
                              "boolean",
                              "null"
                            ]
                          },
                          "nativeSettings": {
                            "additionalProperties": true,
                            "description": "TikTok only, only with `live=true` and only on rows read live. A fixed subset of TikTok's adgroup/get record, not the whole record (snake_case, with TikTok's own names, enums and values). A field TikTok does not return is absent.",
                            "type": "object"
                          },
                          "optimizationGoal": {
                            "description": "The ad set's optimization goal as last synced, in the platform's own enum: Meta: `optimization_goal` (for example OFFSITE_CONVERSIONS or LINK_CLICKS). TikTok: `optimization_goal`.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platform": {
                            "type": "string"
                          },
                          "platformAdAccountId": {
                            "type": "string"
                          },
                          "platformAdSetId": {
                            "type": "string"
                          },
                          "platformAdSetStatus": {
                            "description": "Raw platform ad set status. On TikTok the ad group's own switch `operation_status` (ENABLE / DISABLE), independent of its campaign. On Meta and Reddit the ad set's `effective_status` (e.g. CAMPAIGN_PAUSED).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformCampaignId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformCreatedAt": {
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "promotedObject": {
                            "additionalProperties": true,
                            "description": "Meta only. The ad set's `promoted_object` verbatim (snake_case, for example pixel_id + custom_event_type, page_id, application_id), as last synced from its most recent ad.",
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "schedule": {
                            "description": "The ad set's own flight dates, as synced from the platform. On LinkedIn this is the campaign's `runSchedule`. Null when the platform reports none.",
                            "properties": {
                              "endDate": {
                                "description": "Absent when the ad set runs until it is stopped.",
                                "format": "date-time",
                                "type": "string"
                              },
                              "startDate": {
                                "format": "date-time",
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "status": {
                            "description": "Stored ad set status (active, paused, pending_review, rejected, completed, cancelled, error), as last synced. The `status` filter matches it.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "statusReadAt": {
                            "description": "Only with `live=true`. When `platformAdSetStatus` was read from the platform; null when this row was not read live.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "targeting": {
                            "additionalProperties": true,
                            "description": "The ad set's audience as the platform reported it at the last sync, in the platform's own shape. Every platform.",
                            "properties": {
                              "audienceExpansionEnabled": {
                                "description": "LinkedIn audience expansion: whether LinkedIn may also serve to members similar to the criteria.",
                                "type": "boolean"
                              },
                              "exclude": {
                                "additionalProperties": true,
                                "description": "LinkedIn `targetingCriteria.exclude`, verbatim. Absent when the campaign excludes nothing.",
                                "type": "object"
                              },
                              "include": {
                                "additionalProperties": true,
                                "description": "LinkedIn `targetingCriteria.include`, verbatim (an `and` of `or` facet clauses).",
                                "type": "object"
                              },
                              "offsiteDeliveryEnabled": {
                                "description": "Whether the campaign may deliver on the LinkedIn Audience Network, off LinkedIn itself.",
                                "type": "boolean"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "pagination": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad sets"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List ad sets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_sets@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1be489ff573dadf5166bc8ba931905ac4e8bbe896d8a56600a408d71d43ba001"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_ad_sets",
          "method": "GET",
          "path": "/apis/v1/ads/ad-sets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_ad_sets"
      },
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates an ad set (ad group) that can spend from its own or its campaign's budget. Creates an empty ad group under an existing campaign, ready for ads to be added later. The ad group is created WITHOUT an ad (Google Ads compliance row C.190). Ads join it later via `adSetId` on POST /apis/v1/ads/create. Supports Google Ads and Reddit Ads; every other platform returns 501. Reddit Ads (`platform: reddit`)\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_ad_sets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "campaignId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID: the Google customer ID (digits only, only required when the connection has more than one) or the Reddit ad account id (required).",
                    "type": "string"
                  },
                  "bidAmount": {
                    "description": "Reddit only. Bid cap in currency units, sent with bidStrategy.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "bidStrategy": {
                    "description": "Reddit only. Defaults to LOWEST_COST_WITHOUT_CAP. Not accepted under campaign budget optimization.",
                    "enum": [
                      "LOWEST_COST_WITHOUT_CAP",
                      "LOWEST_COST_WITH_BID_CAP",
                      "COST_CAP"
                    ],
                    "type": "string"
                  },
                  "budgetAmount": {
                    "description": "Reddit only. Budget of the new ad group, in the ad account's currency units. Required when the campaign has no campaign budget; 400 under campaign budget optimization, where the campaign budget funds the ad group.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "budgetType": {
                    "description": "Reddit only. Sent together with budgetAmount.",
                    "enum": [
                      "daily",
                      "lifetime"
                    ],
                    "type": "string"
                  },
                  "campaignId": {
                    "description": "Platform campaign ID the ad group is created under (numeric on Google). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Google only. Alias of adAccountId, kept for existing callers",
                    "type": "string"
                  },
                  "endDate": {
                    "description": "Reddit only. ISO 8601 end of the ad group. Defaults to the campaign end.",
                    "type": "string"
                  },
                  "maxCpc": {
                    "description": "Max CPC of the new ad group, in the account's currency units. Send it when the campaign uses Manual CPC: Google gives an ad group without one a 0.01 bid.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "optimizationGoal": {
                    "description": "Reddit only. VIDEO_VIEW_6S (default) or VIDEO_VIEW_15S on a video views campaign.",
                    "type": "string"
                  },
                  "platform": {
                    "description": "\"google\" and \"reddit\" are implemented; every other value returns 501. Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  },
                  "promotedObject": {
                    "description": "Reddit only. The pixel and the conversion event the ad group optimizes toward.",
                    "properties": {
                      "customEventType": {
                        "description": "Conversion event (PURCHASE, LEAD, SIGN_UP, ADD_TO_CART, PAGE_VISIT). Required on a conversions campaign.",
                        "type": "string"
                      },
                      "pixelId": {
                        "description": "Reddit pixel id. Defaults to the ad account's first pixel.",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "startDate": {
                    "description": "Reddit only. ISO 8601 start of the ad group. Defaults to now, or to the campaign start when it is in the future.",
                    "type": "string"
                  },
                  "status": {
                    "default": "PAUSED",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "targeting": {
                    "description": "Normalized, platform-agnostic ad-targeting spec. Every field is optional; an empty object targets the platform's default broadest audience.",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  }
                },
                "required": [
                  "campaignId",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adSetId": {
                      "description": "Platform id of the new ad group",
                      "type": "string"
                    },
                    "campaignId": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad group created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a standalone ad group",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_set@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "ab9260277fdb37764e92a4439e0f49b7ead60429cdb113102d39a769a0703a75"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_ad_sets",
          "method": "POST",
          "path": "/apis/v1/ads/ad-sets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_ad_sets"
      }
    },
    "/apis/v1/ads/ad-sets/{adSetId}": {
      "delete": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Deletes an ad set and its ads while keeping the campaign, archiving it instead on platforms without a hard delete. Locally, every Ad document under the ad set is marked `status: cancelled`. Delete is soft on platforms that have no hard delete: LinkedIn moves the campaign to `PENDING_DELETION`, Pinterest and Reddit archive the ad group, and X soft-flags the line item. Google removes the ad group.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_ad_sets_adsetid",
        "parameters": [
          {
            "description": "Platform ad set ID",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adCount": {
                      "description": "Local Ad documents marked cancelled (0 for an ad set with no ads)",
                      "type": "integer"
                    },
                    "deleted": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad set deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete an ad set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_set@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e235bcdba7477e61405c474a7dfab59b1bb2d8af7dc947a8d05c1eab9424c358"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_ad_sets_adsetid",
          "method": "DELETE",
          "path": "/apis/v1/ads/ad-sets/{adSetId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_ad_sets_adsetid"
      },
      "get": {
        "description": "Ad Campaigns. Read only. Shows a Meta ad set's current settings straight from Meta, including its learning phase, budget, schedule and targeting. The ad set is read live from Meta and returned verbatim. The default projection includes: `learning_stage_info`: learning-phase status, LEARNING / SUCCESS / FAIL / WAIVING. Meta omits its `status` key on paused ad sets. delivery settings, budgets and schedule\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_ad_sets_adsetid",
        "parameters": [
          {
            "description": "Meta ad set id (platformAdSetId).",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Graph field override.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adSet": {
                      "description": "Raw Meta ad set; keys are the requested Graph fields.",
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The ad set as returned by Meta"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get live ad-set details",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_set_details@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "52133de005747ebb3a9070ca7898395e2c5c076464aeeacfd97fda6a24f32af4"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_ad_sets_adsetid",
          "method": "GET",
          "path": "/apis/v1/ads/ad-sets/{adSetId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_ad_sets_adsetid"
      },
      "put": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Changes an ad set's budget, bidding, schedule, targeting or status. Changes an ad set's settings, such as its budget, bid strategy, status or delivery options. At least one updatable field is required. Use it for: ABO budget updates. Ad-set-scoped pause/resume. Bid-strategy edits. Meta value-rule-set attach/detach.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_ad_sets_adsetid",
        "parameters": [
          {
            "description": "Platform ad set ID",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "budget": {
                  "amount": 10,
                  "type": "daily"
                },
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "bidAmount": {
                    "description": "Bid cap in WHOLE currency units (USD: 5 = $5.00; JPY: 100 = ¥100). Required when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP.",
                    "type": "number"
                  },
                  "bidStrategy": {
                    "description": "Ad-set-level bid strategy. Overrides the campaign-level default. Meta (facebook, instagram): supported. TikTok: the Meta-style enum is mapped to bid_type / bid_price / deep_bid_type automatically.",
                    "enum": [
                      "LOWEST_COST_WITHOUT_CAP",
                      "LOWEST_COST_WITH_BID_CAP",
                      "COST_CAP",
                      "LOWEST_COST_WITH_MIN_ROAS"
                    ],
                    "type": "string"
                  },
                  "budget": {
                    "description": "Omit if not updating budget",
                    "properties": {
                      "amount": {
                        "type": "number"
                      },
                      "type": {
                        "enum": [
                          "daily",
                          "lifetime"
                        ],
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "dsaBeneficiary": {
                    "description": "Meta only (400 elsewhere, before anything in the request is written). Writes the ad set's `dsa_beneficiary`, the legal entity that benefits from its ads. Same field and limits as `dsaBeneficiary` on POST /apis/v1/ads/create.",
                    "maxLength": 100,
                    "minLength": 1,
                    "type": "string"
                  },
                  "dsaPayor": {
                    "description": "Meta only (400 elsewhere, before anything in the request is written). Writes the ad set's `dsa_payor`, the legal entity that pays for its ads, same field and limits as `dsaPayor` on POST /apis/v1/ads/create.",
                    "maxLength": 100,
                    "minLength": 1,
                    "type": "string"
                  },
                  "endDate": {
                    "description": "Reddit only. The ad group's new end_time, ISO 8601, read in the ad account timezone when it has no offset; a date alone means the end of that day. `null` removes the end date so the ad group runs continuously.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "name": {
                    "description": "Rename the ad set. At least one of budget/status/bidStrategy/name is required. Supported on Meta, Google (the ad group), TikTok, LinkedIn (the campaign), Pinterest, X (the line item `name`), OpenAI and Reddit.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "placements": {
                    "description": "Meta only (400 elsewhere). Manual placements, with the same object and enums as `placements` on POST /apis/v1/ads/create.",
                    "properties": {
                      "audienceNetworkPositions": {
                        "items": {
                          "enum": [
                            "classic",
                            "rewarded_video"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "devicePlatforms": {
                        "items": {
                          "enum": [
                            "mobile",
                            "desktop"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "facebookPositions": {
                        "items": {
                          "enum": [
                            "feed",
                            "right_hand_column",
                            "marketplace",
                            "story",
                            "search",
                            "instream_video",
                            "facebook_reels",
                            "facebook_reels_overlay",
                            "profile_feed",
                            "notification"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "instagramPositions": {
                        "items": {
                          "enum": [
                            "stream",
                            "story",
                            "explore",
                            "explore_home",
                            "reels",
                            "profile_feed",
                            "ig_search",
                            "profile_reels"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "messengerPositions": {
                        "items": {
                          "enum": [
                            "messenger_home",
                            "sponsored_messages",
                            "story"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "publisherPlatforms": {
                        "items": {
                          "enum": [
                            "facebook",
                            "instagram",
                            "threads",
                            "messenger",
                            "audience_network",
                            "whatsapp",
                            "meta"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "threadsPositions": {
                        "items": {
                          "enum": [
                            "threads_stream"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "whatsappPositions": {
                        "items": {
                          "enum": [
                            "status"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      }
                    },
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "platform": {
                    "description": "Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  },
                  "platformSpecificData": {
                    "description": "Platform-specific post-launch delivery settings. The platform is implied by the `platform` body param. Meta only; other platforms return 400. Unknown keys are rejected.",
                    "properties": {
                      "adSchedule": {
                        "description": "Replaces the ad set's dayparting (Meta `adset_schedule`, `pacing_type: [\"day_parting\"]`). An empty array removes the schedule (`pacing_type: [\"standard\"]`). Meta runs a schedule only on a lifetime budget.",
                        "items": {
                          "additionalProperties": false,
                          "properties": {
                            "dayOfWeek": {
                              "enum": [
                                "MONDAY",
                                "TUESDAY",
                                "WEDNESDAY",
                                "THURSDAY",
                                "FRIDAY",
                                "SATURDAY",
                                "SUNDAY"
                              ],
                              "type": "string"
                            },
                            "endHour": {
                              "description": "Must be after startHour. 24 is midnight at the end of the day.",
                              "maximum": 24,
                              "minimum": 1,
                              "type": "integer"
                            },
                            "startHour": {
                              "maximum": 23,
                              "minimum": 0,
                              "type": "integer"
                            },
                            "timezoneType": {
                              "default": "USER",
                              "description": "Meta `timezone_type`: USER runs the hours in each viewer's time zone, ADVERTISER in the ad account time zone.",
                              "enum": [
                                "USER",
                                "ADVERTISER"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "dayOfWeek",
                            "endHour",
                            "startHour"
                          ],
                          "type": "object"
                        },
                        "maxItems": 168,
                        "type": "array"
                      },
                      "billingEvent": {
                        "description": "Meta ad-set billing_event (e.g. IMPRESSIONS, LINK_CLICKS, THRUPLAY).",
                        "type": "string"
                      },
                      "customerLifecycle": {
                        "additionalProperties": false,
                        "description": "Meta's Customer Lifecycle Strategy on a Sales ad set (Meta `ad_set_goal`). Rejected with 400 in adSetId attach mode: use PUT /apis/v1/ads/ad-sets/{adSetId} for an ad set that already exists.",
                        "properties": {
                          "engagedAudienceIds": {
                            "description": "Custom audience ids of people who engaged but have not bought. Required with new_customers_excluding_engaged, not allowed with the other strategies. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "existingCustomerAudienceIds": {
                            "description": "Custom audience ids that define your existing customers. Required with both new_customers strategies (Meta answers 400 subcode 1870251 without them); not allowed with all_customers. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "strategy": {
                            "description": "`all_customers` is \"Maximize conversions from all customers\". `new_customers` is \"Acquire new customers\" (excludes existing customers). `new_customers_excluding_engaged` also excludes people who engaged with you but have not bought yet.",
                            "enum": [
                              "all_customers",
                              "new_customers",
                              "new_customers_excluding_engaged"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "strategy"
                        ],
                        "type": "object"
                      },
                      "dailyMinSpendTarget": {
                        "description": "Meta `daily_min_spend_target`: the least this ad set should spend per day, in whole currency units of the ad account. It reserves a share of a CAMPAIGN budget for one ad set, so the campaign must use Advantage campaign budget (CBO).",
                        "type": "number"
                      },
                      "endDate": {
                        "description": "Ad set end_time (ISO 8601). A value without an offset (`YYYY-MM-DD`, `YYYY-MM-DD HH:MM:SS` or `YYYY-MM-DDTHH:MM:SS`) is read in the ad account timezone.",
                        "type": "string"
                      },
                      "lifetimeMinSpendTarget": {
                        "description": "Meta `lifetime_min_spend_target`: the lifetime-budget flavour of `dailyMinSpendTarget`, in whole currency units. Send this one when the campaign budget is a lifetime budget. Same rules and same rejections.",
                        "type": "number"
                      },
                      "optimizationGoal": {
                        "description": "Meta ad-set optimization_goal (e.g. OFFSITE_CONVERSIONS, LANDING_PAGE_VIEWS).",
                        "type": "string"
                      },
                      "promotedObject": {
                        "additionalProperties": false,
                        "description": "Meta ad-set promoted_object (same shape as /apis/v1/ads/create).",
                        "properties": {
                          "applicationId": {
                            "type": "string"
                          },
                          "customConversionId": {
                            "type": "string"
                          },
                          "customEventStr": {
                            "description": "Pixel custom-event name (custom_event_str); requires customEventType OTHER. Same pairing rules as /apis/v1/ads/create.",
                            "type": "string"
                          },
                          "customEventType": {
                            "type": "string"
                          },
                          "objectStoreUrl": {
                            "type": "string"
                          },
                          "offlineConversionDataSetId": {
                            "type": "string"
                          },
                          "pageId": {
                            "type": "string"
                          },
                          "pixelId": {
                            "type": "string"
                          },
                          "productCatalogId": {
                            "type": "string"
                          },
                          "productSetId": {
                            "type": "string"
                          },
                          "whatsappPhoneNumber": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "startDate": {
                        "description": "Ad set start_time (ISO 8601). A value without an offset (`YYYY-MM-DD`, `YYYY-MM-DD HH:MM:SS` or `YYYY-MM-DDTHH:MM:SS`) is read in the ad account timezone.",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "regionalRegulatedCategories": {
                    "description": "Meta only (400 elsewhere, before anything in the request is written).",
                    "items": {
                      "minLength": 1,
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "regionalRegulationIdentities": {
                    "additionalProperties": {
                      "type": [
                        "string",
                        "integer"
                      ]
                    },
                    "description": "Meta only (400 elsewhere, before anything in the request is written). Writes the ad set's `regional_regulation_identities`: the Verified identity IDs of the beneficiary and payer for each declared category.",
                    "type": "object"
                  },
                  "roasAverageFloor": {
                    "description": "Minimum ROAS as a decimal multiplier (2.0 = 2.0x). Required when bidStrategy is LOWEST_COST_WITH_MIN_ROAS. Sent to Meta as `bid_constraints.roas_average_floor` × 10000. Not supported on OpenAI (422).",
                    "type": "number"
                  },
                  "smartTargeting": {
                    "description": "TikTok only (a 400 elsewhere). TikTok Smart Targeting on the ad group: `audience` is TikTok's `smart_audience_enabled`, `interestsBehaviors` its `smart_interest_behavior_enabled`.",
                    "properties": {
                      "audience": {
                        "description": "TikTok smart_audience_enabled.",
                        "type": "boolean"
                      },
                      "interestsBehaviors": {
                        "description": "TikTok smart_interest_behavior_enabled.",
                        "type": "boolean"
                      }
                    },
                    "type": "object"
                  },
                  "startDate": {
                    "description": "Reddit only: the ad group's new start_time, ISO 8601. A value without an offset (`YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SS`) is read in the ad account timezone.",
                    "type": "string"
                  },
                  "status": {
                    "description": "Writes the ad set's own on/off switch (Meta: `configured_status`; X: the line item's `entity_status` ACTIVE / PAUSED), whatever delivery status its ads report. Omit if not toggling delivery state.",
                    "enum": [
                      "active",
                      "paused"
                    ],
                    "type": "string"
                  },
                  "targeting": {
                    "description": "Targeting fields to change. Meta and Reddit (400 elsewhere). Reddit (see the description above):",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "valueRuleSetId": {
                    "description": "Meta only (other platforms return 501). Value rule set to attach to this ad set, from `/apis/v1/ads/value-rule-sets`. Sending a different id replaces the current association. To DETACH, send `valueRulesApplied: false` and omit this field.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "valueRulesApplied": {
                    "description": "Meta only (other platforms return 501). `false` DETACHES the ad set's value rule set and must be sent WITHOUT `valueRuleSetId`; the combination returns 400.",
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "bidAmount": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "bidStrategy": {
                      "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                      "enum": [
                        "LOWEST_COST_WITHOUT_CAP",
                        "LOWEST_COST_WITH_BID_CAP",
                        "COST_CAP",
                        "LOWEST_COST_WITH_MIN_ROAS"
                      ],
                      "type": "string"
                    },
                    "budget": {
                      "description": "Budget amount in the ad account's native currency (see the campaign's `currency` field for the code).",
                      "properties": {
                        "amount": {
                          "type": "number"
                        },
                        "type": {
                          "enum": [
                            "daily",
                            "lifetime"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "amount",
                        "type"
                      ],
                      "type": "object"
                    },
                    "budgetLevel": {
                      "enum": [
                        "adset"
                      ],
                      "type": "string"
                    },
                    "endDate": {
                      "description": "Reddit: the end_time written, a UTC instant, or null when the end date was removed. Present when `endDate` was sent.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "platformAdSetStatus": {
                      "description": "The ad set's status read back from the platform, as in PUT /apis/v1/ads/ad-sets/{adSetId}/status (Meta and Reddit return the ad set's effective_status); null when it could not be read.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "platformCampaignStatus": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "platformSpecificData": {
                      "type": "object"
                    },
                    "roasAverageFloor": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "startDate": {
                      "description": "Reddit: the start_time written, a UTC instant. Present when `startDate` was sent.",
                      "type": "string"
                    },
                    "status": {
                      "description": "As in PUT /apis/v1/ads/ad-sets/{adSetId}/status: delivery derived from the switches read back.",
                      "enum": [
                        "active",
                        "paused"
                      ],
                      "type": "string"
                    },
                    "statusReadAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "statusSkipped": {
                      "description": "1 when a live read showed it already in the requested state.",
                      "enum": [
                        0,
                        1
                      ],
                      "type": "integer"
                    },
                    "statusSkippedReasons": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "statusUpdated": {
                      "description": "1 when the ad set's switch was written.",
                      "enum": [
                        0,
                        1
                      ],
                      "type": "integer"
                    },
                    "targeting": {
                      "description": "Present when `placements` or `targeting` was sent. The ad set's full targeting as written, in the platform's own vocabulary (Meta or Reddit snake_case). Stored as the ad set's `targeting`. Meta stores the same object on its ads.",
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad set updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update an ad set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_set@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "9abe9cf9c14d7fa375927ad898066e953d44d275f93f50bcc45d3bbc7155ce4c"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_ad_sets_adsetid",
          "method": "PUT",
          "path": "/apis/v1/ads/ad-sets/{adSetId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_ad_sets_adsetid"
      }
    },
    "/apis/v1/ads/ad-sets/{adSetId}/assets": {
      "delete": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Detaches assets from a Google ad group without deleting them, so they stay in the account and on anything else they are attached to. Google assets cannot be deleted. Other attachments remain. assetResourceNames is retained for compatibility. Fields go in the query string. A JSON body with the same fields is also accepted and, when sent, the query string is ignored.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets",
        "parameters": [
          {
            "description": "Numeric Google platform id.",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Asset resource names, retained for compatibility. Repeat the parameter or pass a comma-separated list.",
            "in": "query",
            "name": "assetResourceNames",
            "required": true,
            "schema": {
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "type": "array"
            }
          },
          {
            "description": "ad_group_asset resource names to remove, e.g. customers/1234567890/adGroupAssets/456~123~CALLOUT. Repeat the parameter or pass a comma-separated list.",
            "in": "query",
            "name": "adGroupAssetResourceNames",
            "required": true,
            "schema": {
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "type": "array"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "removed": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove ad-group assets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_ad_group_assets@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "519dbd7dfb7044fc2e075b223a89796ea9d852ec179e353ac04e06af33ab41f7"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets",
          "method": "DELETE",
          "path": "/apis/v1/ads/ad-sets/{adSetId}/assets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets"
      },
      "get": {
        "description": "Ad Campaigns. Read only. Lists the sitelinks, callouts, snippets and images attached directly to a Google ad group, not those inherited from the campaign or account. Fresh reads are cached for 10 minutes; exhausted quota may return the last successful read with stale=true. Inherited assets are not included.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets",
        "parameters": [
          {
            "description": "Numeric Google platform id.",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "description": "Alias of adAccountId, kept for existing callers",
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adGroupId": {
                      "type": "string"
                    },
                    "cachedAt": {
                      "description": "Time of the cached Google read. Null when no cache was used.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "callouts": {
                      "items": {
                        "properties": {
                          "adGroupAssetResourceName": {
                            "type": "string"
                          },
                          "assetResourceName": {
                            "type": "string"
                          },
                          "calloutText": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "images": {
                      "items": {
                        "properties": {
                          "adGroupAssetResourceName": {
                            "type": "string"
                          },
                          "assetResourceName": {
                            "type": "string"
                          },
                          "height": {
                            "type": "integer"
                          },
                          "imageUrl": {
                            "description": "Google-hosted copy of the image.",
                            "format": "uri",
                            "type": "string"
                          },
                          "width": {
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "sitelinks": {
                      "items": {
                        "properties": {
                          "adGroupAssetResourceName": {
                            "type": "string"
                          },
                          "assetResourceName": {
                            "type": "string"
                          },
                          "description1": {
                            "type": "string"
                          },
                          "description2": {
                            "type": "string"
                          },
                          "linkUrl": {
                            "format": "uri",
                            "type": "string"
                          },
                          "text": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when exhausted quota required returning the last successful read.",
                      "type": "boolean"
                    },
                    "structuredSnippets": {
                      "items": {
                        "properties": {
                          "adGroupAssetResourceName": {
                            "type": "string"
                          },
                          "assetResourceName": {
                            "type": "string"
                          },
                          "header": {
                            "type": "string"
                          },
                          "values": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List ad-group assets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_group_assets@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "ae668f68c8788a848d5095dc2fa9f3b56f57e952ddee405ad6a535fb8295bd30"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets",
          "method": "GET",
          "path": "/apis/v1/ads/ad-sets/{adSetId}/assets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets"
      },
      "post": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Creates sitelinks, callouts, structured snippets or image assets and attaches them to a Google ad group in one step. Creates and attaches sitelinks, callouts, structured snippets and image assets in one Google mutation. Google shows images only on accounts it deems eligible (account age, policy history, vertical).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets",
        "parameters": [
          {
            "description": "Numeric Google platform id.",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "callouts": [
                  "Fast setup"
                ],
                "connectionId": "adc_7f3k2m9q",
                "customerId": "1234567890",
                "sitelinks": [
                  {
                    "linkUrl": "https://example.com/landing",
                    "text": "Pricing"
                  },
                  {
                    "linkUrl": "https://example.com/landing",
                    "text": "Documentation"
                  }
                ],
                "structuredSnippets": [
                  {
                    "header": "Types",
                    "values": [
                      "Scheduling",
                      "Analytics",
                      "Messaging"
                    ]
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "description": "Provide at least one of sitelinks, callouts, structuredSnippets or images. Sitelink description1 and description2 must be supplied together.",
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "callouts": {
                    "items": {
                      "maxLength": 25,
                      "minLength": 1,
                      "type": "string"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "images": {
                    "description": "Public image URLs, uploaded to Google as image assets. Landscape 1.91:1 (min 600x314) or square 1:1 (min 300x300), up to 5 MB each.",
                    "items": {
                      "format": "uri",
                      "type": "string"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  },
                  "sitelinks": {
                    "items": {
                      "properties": {
                        "description1": {
                          "maxLength": 35,
                          "minLength": 1,
                          "type": "string"
                        },
                        "description2": {
                          "maxLength": 35,
                          "minLength": 1,
                          "type": "string"
                        },
                        "linkUrl": {
                          "format": "uri",
                          "type": "string"
                        },
                        "text": {
                          "maxLength": 25,
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "linkUrl",
                        "text"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 2,
                    "type": "array"
                  },
                  "structuredSnippets": {
                    "items": {
                      "properties": {
                        "header": {
                          "enum": [
                            "Amenities",
                            "Brands",
                            "Courses",
                            "Degree programs",
                            "Destinations",
                            "Featured hotels",
                            "Insurance coverage",
                            "Models",
                            "Neighborhoods",
                            "Service catalog",
                            "Shows",
                            "Styles",
                            "Types"
                          ],
                          "type": "string"
                        },
                        "values": {
                          "items": {
                            "maxLength": 25,
                            "minLength": 1,
                            "type": "string"
                          },
                          "maxItems": 10,
                          "minItems": 3,
                          "type": "array"
                        }
                      },
                      "required": [
                        "header",
                        "values"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adGroupId": {
                      "type": "string"
                    },
                    "calloutAssetResourceNames": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "imageAssetResourceNames": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "sitelinkAssetResourceNames": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "structuredSnippetAssetResourceNames": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets created and attached."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Attach ad-group assets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.attach_ad_group_assets@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0662d9ce7479f2908e07b8eb64b4bd9b153e3a560884f9b6bae6a7022bd0835c"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets",
          "method": "POST",
          "path": "/apis/v1/ads/ad-sets/{adSetId}/assets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets"
      },
      "put": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Edits a Google ad group's existing assets in place; the change applies everywhere that asset is used. Send updates with assetResourceName and the fields to change. An asset is shared: changes affect every attachment using it. Omitted fields stay unchanged. The operation consumes the Google operations budget and invalidates affected cached lists.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets",
        "parameters": [
          {
            "description": "Numeric Google platform id.",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "customerId": "1234567890",
                "updates": [
                  {
                    "assetResourceName": "customers/1234567890/assets/123",
                    "calloutAsset": {
                      "calloutText": "Simple integration"
                    }
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "updates": {
                    "items": {
                      "description": "Supply fields for exactly one asset type per update. finalUrls may accompany sitelinkAsset. Shared asset edits affect every attachment using the asset.",
                      "properties": {
                        "assetResourceName": {
                          "description": "Asset resource name returned by a list operation. Must belong to the selected customer.",
                          "pattern": "^customers/\\d+/assets/\\d+$",
                          "type": "string"
                        },
                        "calloutAsset": {
                          "properties": {
                            "calloutText": {
                              "maxLength": 25,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "calloutText"
                          ],
                          "type": "object"
                        },
                        "finalUrls": {
                          "items": {
                            "format": "uri",
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "sitelinkAsset": {
                          "properties": {
                            "description1": {
                              "maxLength": 35,
                              "type": "string"
                            },
                            "description2": {
                              "maxLength": 35,
                              "type": "string"
                            },
                            "linkText": {
                              "maxLength": 25,
                              "minLength": 1,
                              "type": "string"
                            },
                            "linkUrl": {
                              "description": "Alias for finalUrls with one URL. Do not supply both.",
                              "format": "uri",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "structuredSnippetAsset": {
                          "properties": {
                            "header": {
                              "enum": [
                                "Amenities",
                                "Brands",
                                "Courses",
                                "Degree programs",
                                "Destinations",
                                "Featured hotels",
                                "Insurance coverage",
                                "Models",
                                "Neighborhoods",
                                "Service catalog",
                                "Shows",
                                "Styles",
                                "Types"
                              ],
                              "type": "string"
                            },
                            "values": {
                              "items": {
                                "maxLength": 25,
                                "minLength": 1,
                                "type": "string"
                              },
                              "maxItems": 10,
                              "minItems": 3,
                              "type": "array"
                            }
                          },
                          "required": [
                            "header",
                            "values"
                          ],
                          "type": "object"
                        }
                      },
                      "required": [
                        "assetResourceName"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "updates"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "updated": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update ad-group assets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_group_assets@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "40c4ee9129dba1451f8fce98447b843d3fd5165bf51a27f5b20359cdd04e2735"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets",
          "method": "PUT",
          "path": "/apis/v1/ads/ad-sets/{adSetId}/assets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_ad_sets_adsetid_assets"
      }
    },
    "/apis/v1/ads/ad-sets/{adSetId}/duplicate": {
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Copies an ad set, with its budget; an active copy starts spending. Copies an ad set, optionally with its ads and into another campaign, created paused so you can review it before launch. The copy is created paused so callers can review before launching. `campaignId` retargets the copy into another campaign; omitted = the source's own campaign. Meta: ads and creatives are included by default (`deepCopy: true`).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_ad_sets_adsetid_duplicate",
        "parameters": [
          {
            "description": "Source platform ad set ID",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "campaignId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "deepCopy": true
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "campaignId": {
                    "description": "Destination platform campaign id (defaults to the source's campaign) Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "deepCopy": {
                    "default": true,
                    "description": "Copy child ads + creatives",
                    "type": "boolean"
                  },
                  "endTime": {
                    "description": "Reschedule the copy's end, read like `startTime`; a date-only end runs to 23:59:59 local.",
                    "format": "date-time",
                    "type": "string"
                  },
                  "platform": {
                    "description": "Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "meta"
                    ],
                    "type": "string"
                  },
                  "renamePrefix": {
                    "description": "Text prepended to each renamed object's name.",
                    "type": "string"
                  },
                  "renameStrategy": {
                    "description": "Meta's native `rename_strategy` values: `DEEP_RENAME`: renames the copied ad set and its copied ads with `renamePrefix` / `renameSuffix`. `ONLY_TOP_LEVEL_RENAME`: renames only the copied ad set; its ads keep their source names.",
                    "enum": [
                      "DEEP_RENAME",
                      "ONLY_TOP_LEVEL_RENAME",
                      "NO_RENAME"
                    ],
                    "type": "string"
                  },
                  "renameSuffix": {
                    "description": "Text appended to each renamed object's name.",
                    "type": "string"
                  },
                  "startTime": {
                    "description": "Reschedule the copy's start (ISO 8601). A value without an offset (`YYYY-MM-DD`, `YYYY-MM-DD HH:MM:SS` or `YYYY-MM-DDTHH:MM:SS`) is read in the ad account timezone.",
                    "format": "date-time",
                    "type": "string"
                  },
                  "statusOption": {
                    "default": "PAUSED",
                    "enum": [
                      "ACTIVE",
                      "PAUSED",
                      "INHERITED_FROM_SOURCE"
                    ],
                    "type": "string"
                  },
                  "syncAfter": {
                    "default": true,
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adIdMap": {
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Meta only: source ad ID to copied ad ID. Empty when `deepCopy` is false.",
                      "type": "object"
                    },
                    "copiedAdIds": {
                      "description": "Platform IDs of the copied ads",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "copiedAdSetId": {
                      "description": "Platform ID of the new ad set",
                      "type": "string"
                    },
                    "discovery": {
                      "enum": [
                        "triggered",
                        "skipped",
                        "failed"
                      ],
                      "type": "string"
                    },
                    "raw": {
                      "description": "Platform-native response from the copy (TikTok). Absent on Meta, which returns `adIdMap` instead.",
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad set duplicated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Duplicate an ad set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.duplicate_ad_set@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "495aa3672b899aa692be91238fe70c6e08c50f4ff1bccef8e3bbeb3ed56ad755"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_ad_sets_adsetid_duplicate",
          "method": "POST",
          "path": "/apis/v1/ads/ad-sets/{adSetId}/duplicate"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_ad_sets_adsetid_duplicate"
      }
    },
    "/apis/v1/ads/ad-sets/{adSetId}/status": {
      "put": {
        "description": "Ad Campaigns. A pause needs ads:write. A change to active turns delivery on: it needs ads:spend and X-Aisa-Confirm: spend. Pauses or resumes one ad set without touching its campaign, its sibling ad sets or the switches of its ads. It is a thin wrapper over PUT /apis/v1/ads/ad-sets/{adSetId} for callers that only want the status toggle and prefer a symmetric URL to /apis/v1/ads/campaigns/{campaignId}/status. ### What is written It writes the ad set's own on/off switch and nothing else, on every platform:\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_ad_sets_adsetid_status",
        "parameters": [
          {
            "description": "Platform ad set ID",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "status": "active"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "platform": {
                    "description": "Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "microsoft",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  },
                  "status": {
                    "enum": [
                      "active",
                      "paused"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "status"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "platformAdSetStatus": {
                      "description": "The ad set's own switch as read back from the platform (as GET /apis/v1/ads/ad-sets returns it), in raw platform vocabulary. Null when the platform could not be read, which is always the case on X. Meta: effective_status.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "platformCampaignStatus": {
                      "description": "The parent campaign's switch, read in the same call where the platform returns it, otherwise the stored value.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "skipped": {
                      "description": "1 when a live read showed the ad set already in the requested state, so nothing was written.",
                      "enum": [
                        0,
                        1
                      ],
                      "type": "integer"
                    },
                    "skippedReasons": {
                      "description": "Why the write was skipped, for example \"Ad set already switched off\".",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "status": {
                      "description": "The ad set's delivery status derived from the switches read back: `paused` when its own switch or its campaign's switch is off. Echoes the request when the platform could not be read.",
                      "enum": [
                        "active",
                        "paused"
                      ],
                      "type": "string"
                    },
                    "statusReadAt": {
                      "description": "When the ad set switch was read back. Null when it could not be read.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "updated": {
                      "description": "1 when the ad set's switch was written.",
                      "enum": [
                        0,
                        1
                      ],
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad set status updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Pause or resume a single ad set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_set_status@1",
          "required_scope": "ads:write",
          "scope_rule": "Pausing needs ads:write; turning delivery on needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "c756bdd964a74b1cdc089aa78be3826b7c7a146ed4c8699f0f1d88ae99ac5ec6"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_ad_sets_adsetid_status",
          "method": "PUT",
          "path": "/apis/v1/ads/ad-sets/{adSetId}/status"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_ad_sets_adsetid_status"
      }
    },
    "/apis/v1/ads/ad-sets/{adSetId}/targeting": {
      "get": {
        "description": "Ad Campaigns. Read only. Shows a Reddit ad group's live targeting and schedule in the same shape PUT /apis/v1/ads/ad-sets/{adSetId} takes, so you can prefill an editor. It is read live from Reddit on every call. Reddit only; every other platform returns 501. ### How fields come back Location and interest names are resolved with Reddit's targeting taxonomy.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_ad_sets_adsetid_targeting",
        "parameters": [
          {
            "description": "Reddit ad group ID",
            "in": "path",
            "name": "adSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Disambiguates when the same adSetId string exists on more than one connected platform.",
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "reddit"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adSetId": {
                      "type": "string"
                    },
                    "endDate": {
                      "description": "The ad group's end_time, null when it runs continuously.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "startDate": {
                      "description": "The ad group's start_time, null when it has none.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "targeting": {
                      "description": "Only the keys the ad group sets. `regions`, `metros`, `cities` and `zips` entries carry `{ key, name }`; `interests` carry `{ id, name }`.",
                      "properties": {
                        "ageMax": {
                          "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                          "maximum": 100,
                          "minimum": 13,
                          "type": "integer"
                        },
                        "ageMin": {
                          "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                          "maximum": 100,
                          "minimum": 13,
                          "type": "integer"
                        },
                        "audienceExclude": {
                          "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400).",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "audienceInclude": {
                          "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences).",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "behaviors": {
                          "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                          "items": {
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "cities": {
                          "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                          "items": {
                            "oneOf": [
                              {
                                "type": "string"
                              },
                              {
                                "properties": {
                                  "distanceUnit": {
                                    "description": "Required if radius is set.",
                                    "enum": [
                                      "mile",
                                      "kilometer"
                                    ],
                                    "type": "string"
                                  },
                                  "key": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "radius": {
                                    "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                    "type": "number"
                                  }
                                },
                                "required": [
                                  "key"
                                ],
                                "type": "object"
                              }
                            ]
                          },
                          "type": "array"
                        },
                        "communities": {
                          "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                          "items": {
                            "minLength": 1,
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "companySizes": {
                          "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "conversationKeywords": {
                          "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                          "items": {
                            "minLength": 1,
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "countries": {
                          "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "countryGroups": {
                          "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                          "items": {
                            "enum": [
                              "africa",
                              "asia",
                              "europe",
                              "north_america",
                              "south_america",
                              "oceania",
                              "central_america",
                              "caribbean",
                              "eea",
                              "euro_area",
                              "nafta",
                              "mercosur",
                              "afta",
                              "apec",
                              "gcc",
                              "cisfta",
                              "emerging_markets",
                              "itunes_app_store",
                              "android_free_store",
                              "android_paid_store"
                            ],
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "customLocations": {
                          "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                          "items": {
                            "properties": {
                              "address": {
                                "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                "type": "string"
                              },
                              "distanceUnit": {
                                "enum": [
                                  "mile",
                                  "kilometer"
                                ],
                                "type": "string"
                              },
                              "latitude": {
                                "maximum": 90,
                                "minimum": -90,
                                "type": "number"
                              },
                              "longitude": {
                                "maximum": 180,
                                "minimum": -180,
                                "type": "number"
                              },
                              "name": {
                                "type": "string"
                              },
                              "radius": {
                                "description": "Positive radius around the point.",
                                "type": "number"
                              }
                            },
                            "required": [
                              "distanceUnit",
                              "latitude",
                              "longitude",
                              "radius"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "excludedCommunities": {
                          "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                          "items": {
                            "minLength": 1,
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "excludedConversationKeywords": {
                          "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                          "items": {
                            "minLength": 1,
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "excludedLocations": {
                          "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                          "properties": {
                            "cities": {
                              "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "type": "array"
                            },
                            "countries": {
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "countryGroups": {
                              "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                              "items": {
                                "enum": [
                                  "africa",
                                  "asia",
                                  "europe",
                                  "north_america",
                                  "south_america",
                                  "oceania",
                                  "central_america",
                                  "caribbean",
                                  "eea",
                                  "euro_area",
                                  "nafta",
                                  "mercosur",
                                  "afta",
                                  "apec",
                                  "gcc",
                                  "cisfta",
                                  "emerging_markets",
                                  "itunes_app_store",
                                  "android_free_store",
                                  "android_paid_store"
                                ],
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "customLocations": {
                              "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "type": "array"
                            },
                            "neighborhoods": {
                              "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "type": "array"
                            },
                            "places": {
                              "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "type": "array"
                            },
                            "regions": {
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "type": "array"
                            },
                            "zips": {
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "type": "array"
                            }
                          },
                          "type": "object"
                        },
                        "gender": {
                          "description": "Restrict by gender. 'all' (default) targets everyone.",
                          "enum": [
                            "all",
                            "male",
                            "female"
                          ],
                          "type": "string"
                        },
                        "incomeTier": {
                          "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                          "enum": [
                            "top_5",
                            "top_10",
                            "top_10_25",
                            "top_25_50"
                          ],
                          "type": "string"
                        },
                        "industries": {
                          "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "interests": {
                          "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                          "items": {
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "jobFunctions": {
                          "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "languages": {
                          "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "metros": {
                          "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                          "items": {
                            "properties": {
                              "key": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "key"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "regions": {
                          "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                          "items": {
                            "oneOf": [
                              {
                                "type": "string"
                              },
                              {
                                "properties": {
                                  "key": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "key"
                                ],
                                "type": "object"
                              }
                            ]
                          },
                          "type": "array"
                        },
                        "seniorities": {
                          "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "skills": {
                          "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "userDevice": {
                          "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                          "items": {
                            "minLength": 1,
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "userOs": {
                          "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                          "items": {
                            "minLength": 1,
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "workEmployers": {
                          "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                          "items": {
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "workIndustries": {
                          "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                          "items": {
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "workPositions": {
                          "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                          "items": {
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "zips": {
                          "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                          "items": {
                            "properties": {
                              "key": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "key"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Current ad group targeting and schedule"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Read a Reddit ad group's targeting and schedule",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_set_targeting@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "32b69c40d6dff80522b076c1551d545f8a5776375ca6da8b18c9001a0df90d5b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_ad_sets_adsetid_targeting",
          "method": "GET",
          "path": "/apis/v1/ads/ad-sets/{adSetId}/targeting"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_ad_sets_adsetid_targeting"
      }
    },
    "/apis/v1/ads/advertisable-applications": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the mobile apps a Meta ad account can promote, with their platforms and store links, for app install campaigns. Lists applications available to a Meta ad account, their supported platforms and unmodified object store URLs. A listed app still needs a configured mobile platform and store URL to run install promotion.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_advertisable_applications",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account ID including the act_ prefix.",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "pattern": "^act_[0-9]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "applications": {
                      "items": {
                        "properties": {
                          "id": {
                            "description": "Meta application ID.",
                            "type": "string"
                          },
                          "name": {
                            "description": "Application name.",
                            "type": "string"
                          },
                          "storeUrls": {
                            "additionalProperties": {
                              "type": "string"
                            },
                            "description": "Platform-keyed store URLs returned unchanged by Meta.",
                            "type": "object"
                          },
                          "supportedPlatforms": {
                            "description": "Platform identifiers reported by Meta.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "storeUrls",
                          "supportedPlatforms"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "applications"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Applications available for promotion."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List advertisable apps",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_advertisable_applications@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "7e785344fa13d8014cdd019b91c5445670160e0a9aa7ed4a1b6b46d4fb7dd77d"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_advertisable_applications",
          "method": "GET",
          "path": "/apis/v1/ads/advertisable-applications"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_advertisable_applications"
      }
    },
    "/apis/v1/ads/alerts": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists what needs attention across your ads, most severe first: ads created in the last 90 days that were rejected campaigns the platform reports delivery issues on Meta ad accounts with a failed or overdue payment, or disabled while holding live ads campaigns that spent on 3 or more of the last 7 days without a result (conversion, lead, purchase or conversation goals)\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_alerts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Also return dismissed alerts, with `dismissed: true`.",
            "in": "query",
            "name": "includeDismissed",
            "required": false,
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "alerts": {
                      "items": {
                        "properties": {
                          "adId": {
                            "type": "string"
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "currency": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "detectedAt": {
                            "format": "date-time",
                            "type": "string"
                          },
                          "dismissed": {
                            "type": "boolean"
                          },
                          "entity": {
                            "properties": {
                              "id": {
                                "description": "The platform id of the entity.",
                                "type": "string"
                              },
                              "level": {
                                "enum": [
                                  "ad_account",
                                  "campaign",
                                  "ad_set",
                                  "ad"
                                ],
                                "type": "string"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": "object"
                          },
                          "fix": {
                            "properties": {
                              "label": {
                                "type": "string"
                              },
                              "url": {
                                "format": "uri-reference",
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "id": {
                            "description": "Stable for the same problem on the same entity. Pass it to POST /apis/v1/ads/alerts/{alertId}/dismiss.",
                            "type": "string"
                          },
                          "kind": {
                            "enum": [
                              "ad_rejected",
                              "delivery_issue",
                              "payment",
                              "budget_limited",
                              "spend_no_results",
                              "connection_lost",
                              "sync_failing"
                            ],
                            "type": "string"
                          },
                          "message": {
                            "description": "What happened, in plain words. For a rejection or delivery issue, the platform's own reason when it gave one.",
                            "type": "string"
                          },
                          "platform": {
                            "type": "string"
                          },
                          "platformAdAccountId": {
                            "type": "string"
                          },
                          "severity": {
                            "enum": [
                              "error",
                              "warning",
                              "info"
                            ],
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "counts": {
                      "description": "Open (not dismissed) alerts per severity.",
                      "properties": {
                        "error": {
                          "type": "integer"
                        },
                        "info": {
                          "type": "integer"
                        },
                        "warning": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Alerts, most severe first."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List ads that need attention",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ads_alerts@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e58cb4d470b081cf2d8edc71029163fb2c722b14731065eeebf7230b81b9af1b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_alerts",
          "method": "GET",
          "path": "/apis/v1/ads/alerts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_alerts"
      }
    },
    "/apis/v1/ads/alerts/{alertId}/dismiss": {
      "post": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Hides an alert from `GET /apis/v1/ads/alerts` for 30 days for the calling user. If the problem is still there after that, the alert comes back.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_alerts_alertid_dismiss",
        "parameters": [
          {
            "description": "The `id` of an alert from GET /apis/v1/ads/alerts.",
            "in": "path",
            "name": "alertId",
            "required": true,
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "dismissed": {
                      "type": "boolean"
                    },
                    "dismissedUntil": {
                      "format": "date-time",
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Dismissed."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Dismiss an ads alert",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.dismiss_ads_alert@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "2ba1ab42895ba942a074cb0c1e3f19a4df04641d7894bcb2692f2415d34d6c95"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_alerts_alertid_dismiss",
          "method": "POST",
          "path": "/apis/v1/ads/alerts/{alertId}/dismiss"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_alerts_alertid_dismiss"
      }
    },
    "/apis/v1/ads/audiences": {
      "get": {
        "description": "Ad Audiences. Read only. Lists the custom audiences in an ad account so you can reuse them for targeting. Supports Meta, Google, TikTok, Pinterest, LinkedIn, X, and Reddit. On Reddit, `size` is the lower bound of Reddit's matched-users range, and `status` is `too_small` while the list has matched fewer than 1,000 people.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_audiences",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "facebook",
                "instagram",
                "googleads",
                "tiktok",
                "tiktokads",
                "pinterest",
                "linkedin",
                "linkedinads",
                "twitter",
                "xads",
                "redditads",
                "meta",
                "x"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter to one audience type. `saved_targeting` returns stored TargetingSpec audiences; the other types return uploaded/derived audiences.",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "enum": [
                "customer_list",
                "company_list",
                "engagement",
                "meta_engagement",
                "website",
                "website_retargeting",
                "lookalike",
                "saved_targeting"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "audiences": {
                      "items": {
                        "properties": {
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "description": {
                            "type": "string"
                          },
                          "id": {
                            "description": "Pass this as audienceId on GET /apis/v1/ads/audiences/{audienceId} and the companies/users upload endpoints.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "platform": {
                            "type": "string"
                          },
                          "platformAudienceId": {
                            "type": "string"
                          },
                          "size": {
                            "type": "integer"
                          },
                          "spec": {
                            "anyOf": [
                              {
                                "description": "Normalized, platform-agnostic ad-targeting spec. Every field is optional; an empty object targets the platform's default broadest audience.",
                                "properties": {
                                  "ageMax": {
                                    "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                                    "maximum": 100,
                                    "minimum": 13,
                                    "type": "integer"
                                  },
                                  "ageMin": {
                                    "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                                    "maximum": 100,
                                    "minimum": 13,
                                    "type": "integer"
                                  },
                                  "audienceExclude": {
                                    "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400).",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "audienceInclude": {
                                    "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences).",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "behaviors": {
                                    "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "cities": {
                                    "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                                    "items": {
                                      "oneOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "additionalProperties": true,
                                          "type": "object"
                                        }
                                      ]
                                    },
                                    "type": "array"
                                  },
                                  "communities": {
                                    "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                                    "items": {
                                      "minLength": 1,
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "companySizes": {
                                    "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "conversationKeywords": {
                                    "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                                    "items": {
                                      "minLength": 1,
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "countries": {
                                    "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "countryGroups": {
                                    "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                                    "items": {
                                      "enum": [
                                        "africa",
                                        "asia",
                                        "europe",
                                        "north_america",
                                        "south_america",
                                        "oceania",
                                        "central_america",
                                        "caribbean",
                                        "eea",
                                        "euro_area",
                                        "nafta",
                                        "mercosur",
                                        "afta",
                                        "apec",
                                        "gcc",
                                        "cisfta",
                                        "emerging_markets",
                                        "itunes_app_store",
                                        "android_free_store",
                                        "android_paid_store"
                                      ],
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "customLocations": {
                                    "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "excludedCommunities": {
                                    "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                                    "items": {
                                      "minLength": 1,
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "excludedConversationKeywords": {
                                    "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                                    "items": {
                                      "minLength": 1,
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "excludedLocations": {
                                    "additionalProperties": true,
                                    "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                                    "type": "object"
                                  },
                                  "gender": {
                                    "description": "Restrict by gender. 'all' (default) targets everyone.",
                                    "enum": [
                                      "all",
                                      "male",
                                      "female"
                                    ],
                                    "type": "string"
                                  },
                                  "incomeTier": {
                                    "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                                    "enum": [
                                      "top_5",
                                      "top_10",
                                      "top_10_25",
                                      "top_25_50"
                                    ],
                                    "type": "string"
                                  },
                                  "industries": {
                                    "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "interests": {
                                    "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "jobFunctions": {
                                    "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "languages": {
                                    "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "metros": {
                                    "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "regions": {
                                    "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                                    "items": {
                                      "oneOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "additionalProperties": true,
                                          "type": "object"
                                        }
                                      ]
                                    },
                                    "type": "array"
                                  },
                                  "seniorities": {
                                    "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "skills": {
                                    "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "userDevice": {
                                    "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                                    "items": {
                                      "minLength": 1,
                                      "type": "string"
                                    },
                                    "minItems": 1,
                                    "type": "array"
                                  },
                                  "userOs": {
                                    "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                                    "items": {
                                      "minLength": 1,
                                      "type": "string"
                                    },
                                    "minItems": 1,
                                    "type": "array"
                                  },
                                  "workEmployers": {
                                    "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "workIndustries": {
                                    "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "workPositions": {
                                    "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "zips": {
                                    "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  }
                                },
                                "type": "object"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Present (and the only meaningful payload) when `type` is `saved_targeting`. Null for uploaded/derived audience types."
                          },
                          "status": {
                            "type": "string"
                          },
                          "type": {
                            "description": "`reddit_engagement`, `third_party` and `in_market` are listed from Reddit (engagement retargeting, and Reddit's own audiences) so they can be targeted.",
                            "enum": [
                              "customer_list",
                              "company_list",
                              "engagement",
                              "meta_engagement",
                              "tiktok_engagement",
                              "pinterest_engagement",
                              "website",
                              "website_retargeting",
                              "lookalike",
                              "saved_targeting",
                              "reddit_engagement",
                              "third_party",
                              "in_market"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Audiences"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List custom audiences",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_audiences@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "f845839e0e26fef5b6df79ec720a197ce992636cadbe505210f581a097382a2b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_audiences",
          "method": "GET",
          "path": "/apis/v1/ads/audiences"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_audiences"
      },
      "post": {
        "description": "Ad Audiences. Changes the ad account without starting or raising spend; audited. Creates a custom audience from a customer list, website visitors, a lookalike, or people who engaged with your content. ### Audience types by platform `customer_list`: Meta, Google, X, LinkedIn, TikTok, Pinterest, and Reddit. `website` (pixel/tag visitors): Meta, TikTok, Pinterest, Google, and Reddit. `lookalike`: Meta, TikTok, Pinterest and Google (Reddit's API cannot create one).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_audiences",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch",
                "type": "customer_list"
              },
              "schema": {
                "additionalProperties": true,
                "oneOf": [
                  {
                    "description": "customer_list, website, lookalike or engagement audience (uploaded or derived from a source).",
                    "properties": {
                      "adAccountId": {
                        "description": "Platform ad account ID. Must start with act_ for Meta; bare platform id for others (Google customer id, X/TikTok/LinkedIn/Pinterest account id).",
                        "type": "string"
                      },
                      "adIds": {
                        "description": "pinterest_engagement: people who engaged with these ads. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "pattern": "^\\d+$",
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "campaignIds": {
                        "description": "pinterest_engagement: people who engaged with these campaigns' ads. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "pattern": "^\\d+$",
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companies": {
                        "description": "Required for company_list audiences (LinkedIn only). Plain-text company rows for account targeting; each row needs at least one identifier. Not hashed: LinkedIn matches these against its own company graph.",
                        "items": {
                          "additionalProperties": false,
                          "properties": {
                            "domain": {
                              "maxLength": 100,
                              "type": "string"
                            },
                            "linkedinPageUrl": {
                              "type": "string"
                            },
                            "name": {
                              "maxLength": 255,
                              "type": "string"
                            },
                            "website": {
                              "maxLength": 100,
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "maxItems": 300000,
                        "minItems": 1,
                        "type": "array"
                      },
                      "country": {
                        "description": "2-letter code, required for lookalike audiences",
                        "type": "string"
                      },
                      "customerFileSource": {
                        "description": "Data source declaration for GDPR compliance (customer_list only)",
                        "type": "string"
                      },
                      "description": {
                        "type": "string"
                      },
                      "engagementDomains": {
                        "description": "pinterest_engagement: people who engaged with Pins from these domains. The domain must be claimed on the Pinterest account or Pinterest rejects it.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "engagementSource": {
                        "description": "Required for meta_engagement audiences (Meta only): what people engaged with. `page` = a Facebook Page, `instagram` = an IG professional account, `video` = a video.",
                        "enum": [
                          "page",
                          "instagram",
                          "video"
                        ],
                        "type": "string"
                      },
                      "engagementSources": {
                        "description": "Required for engagement audiences. Campaign URNs for the ad source types, organization URNs for pages and events. LinkedIn creates one rule per source, all sharing the same trigger and lookbackDays.",
                        "items": {
                          "type": "string"
                        },
                        "maxItems": 50,
                        "minItems": 1,
                        "type": "array"
                      },
                      "engagementType": {
                        "description": "pinterest_engagement: limit to one engagement action.",
                        "enum": [
                          "click",
                          "save",
                          "closeup",
                          "comment",
                          "like"
                        ],
                        "type": "string"
                      },
                      "engagerType": {
                        "description": "pinterest_engagement: Pinterest's `engager_type`, passed through when set.",
                        "enum": [
                          1,
                          2
                        ],
                        "type": "integer"
                      },
                      "event": {
                        "description": "The event to match. Its meaning depends on the type: meta_engagement: the engagement event. Defaults per source (page → page_engaged, instagram → ig_business_profile_all, video → video_watched). Ignored when `rule` is provided.",
                        "maxLength": 100,
                        "type": "string"
                      },
                      "identityAuthorizedBcId": {
                        "description": "tiktok_engagement: required when identityType is BC_AUTH_TT.",
                        "type": "string"
                      },
                      "identityId": {
                        "description": "tiktok_engagement: the TikTok identity that owns the videos or business account. Required for organic_video, live_video and business_account.",
                        "type": "string"
                      },
                      "identityType": {
                        "description": "tiktok_engagement: type of `identityId`.",
                        "enum": [
                          "TT_USER",
                          "BC_AUTH_TT"
                        ],
                        "type": "string"
                      },
                      "lookbackDays": {
                        "description": "Required for engagement audiences. Rolling window.",
                        "enum": [
                          30,
                          60,
                          90,
                          180,
                          365
                        ],
                        "type": "integer"
                      },
                      "matchRules": {
                        "description": "Required for website_retargeting audiences (LinkedIn only). Each rule is a URL pattern; a member who visits any matching page enters the segment.",
                        "items": {
                          "additionalProperties": false,
                          "properties": {
                            "matchType": {
                              "enum": [
                                "EXACT",
                                "STARTS_WITH",
                                "CONTAINS",
                                "ENDS_WITH"
                              ],
                              "type": "string"
                            },
                            "matchValue": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "matchType",
                            "matchValue"
                          ],
                          "type": "object"
                        },
                        "maxItems": 50,
                        "minItems": 1,
                        "type": "array"
                      },
                      "name": {
                        "maxLength": 255,
                        "type": "string"
                      },
                      "pinIds": {
                        "description": "pinterest_engagement: people who engaged with these Pins. At least one of engagementDomains, campaignIds, adIds or pinIds is required.",
                        "items": {
                          "pattern": "^\\d+$",
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "pixelId": {
                        "description": "website: the Meta pixel, TikTok pixel, Pinterest tag or Reddit pixel id. Required on those four, rejected on Google.",
                        "type": "string"
                      },
                      "ratio": {
                        "description": "lookalike on Meta (0.01-0.20) and Pinterest (0.01-0.10, whole percents). Rejected on TikTok and Google.",
                        "maximum": 0.2,
                        "minimum": 0.01,
                        "type": "number"
                      },
                      "retentionDays": {
                        "description": "Required for website (Meta max 180, TikTok 7/14/30/60/90/180, Reddit max 90, Pinterest and Google max 540), meta_engagement (max 365) and tiktok_engagement (7/14/30/60/90/180; organic and live video and most business-account events only…",
                        "maximum": 540,
                        "minimum": 1,
                        "type": "integer"
                      },
                      "rule": {
                        "description": "Meta only (a 400 elsewhere). Optional raw Meta rule, replacing the one we build. Omit it for all visitors of `pixelId`, or use `urlContains` for the common page-match case.",
                        "type": "object"
                      },
                      "size": {
                        "description": "lookalike on TikTok and Google: audience breadth. Rejected on Meta and Pinterest.",
                        "enum": [
                          "narrow",
                          "balanced",
                          "broad"
                        ],
                        "type": "string"
                      },
                      "source": {
                        "description": "Required for tiktok_engagement: what people engaged with.",
                        "enum": [
                          "ads",
                          "organic_video",
                          "live_video",
                          "business_account"
                        ],
                        "type": "string"
                      },
                      "sourceAudienceId": {
                        "description": "Required for lookalike audiences Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "type": "string"
                      },
                      "sourceId": {
                        "description": "Required for meta_engagement: the Page / IG account / video id.",
                        "type": "string"
                      },
                      "sourceIds": {
                        "description": "tiktok_engagement: ad group / campaign ids for `ads`, video ids for `organic_video` and `live_video` (max 10). Required except for `business_account`.",
                        "items": {
                          "type": "string"
                        },
                        "maxItems": 50,
                        "minItems": 1,
                        "type": "array"
                      },
                      "sourceType": {
                        "description": "Required for engagement audiences (LinkedIn only): what members engaged with: a video/leadgen/single-image ad campaign, a Company Page or an Event page.",
                        "enum": [
                          "VIDEO_ADS",
                          "LEAD_GEN_FORMS",
                          "ORGANIZATION_PAGES",
                          "EVENT_PAGES",
                          "SINGLE_IMAGE_ADS"
                        ],
                        "type": "string"
                      },
                      "trigger": {
                        "description": "Required for engagement audiences. The action, validated by LinkedIn against `sourceType`.",
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "customer_list",
                          "company_list",
                          "engagement",
                          "meta_engagement",
                          "tiktok_engagement",
                          "pinterest_engagement",
                          "website",
                          "website_retargeting",
                          "lookalike"
                        ],
                        "type": "string"
                      },
                      "urlContains": {
                        "description": "website on Meta, TikTok and Google. Narrows the audience from all visitors to visitors of URLs containing this substring. Ignored when `rule` is supplied. A 400 on Pinterest, which only matches exact URLs.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "adAccountId",
                      "name",
                      "type"
                    ],
                    "type": "object"
                  },
                  {
                    "description": "A reusable, stored TargetingSpec. No member upload step, no adAccountId, the spec is the audience. Reference it later via `savedTargetingId` on POST /apis/v1/ads/create.",
                    "properties": {
                      "description": {
                        "type": "string"
                      },
                      "name": {
                        "maxLength": 255,
                        "type": "string"
                      },
                      "spec": {
                        "description": "The targeting spec to store.",
                        "properties": {
                          "ageMax": {
                            "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                            "maximum": 100,
                            "minimum": 13,
                            "type": "integer"
                          },
                          "ageMin": {
                            "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                            "maximum": 100,
                            "minimum": 13,
                            "type": "integer"
                          },
                          "audienceExclude": {
                            "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "audienceInclude": {
                            "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "behaviors": {
                            "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                            "items": {
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "cities": {
                            "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                            "items": {
                              "oneOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "properties": {
                                    "distanceUnit": {
                                      "description": "Required if radius is set.",
                                      "enum": [
                                        "mile",
                                        "kilometer"
                                      ],
                                      "type": "string"
                                    },
                                    "key": {
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    },
                                    "radius": {
                                      "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                }
                              ]
                            },
                            "type": "array"
                          },
                          "communities": {
                            "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                            "items": {
                              "minLength": 1,
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "companySizes": {
                            "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "conversationKeywords": {
                            "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                            "items": {
                              "minLength": 1,
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "excludedCommunities": {
                            "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                            "items": {
                              "minLength": 1,
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "excludedConversationKeywords": {
                            "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                            "items": {
                              "minLength": 1,
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "excludedLocations": {
                            "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                            "properties": {
                              "cities": {
                                "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                                "items": {
                                  "properties": {
                                    "distanceUnit": {
                                      "description": "Required if radius is set.",
                                      "enum": [
                                        "mile",
                                        "kilometer"
                                      ],
                                      "type": "string"
                                    },
                                    "key": {
                                      "type": "string"
                                    },
                                    "radius": {
                                      "description": "Radius around the excluded city. Requires distanceUnit.",
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "countries": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "countryGroups": {
                                "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                                "items": {
                                  "enum": [
                                    "africa",
                                    "asia",
                                    "europe",
                                    "north_america",
                                    "south_america",
                                    "oceania",
                                    "central_america",
                                    "caribbean",
                                    "eea",
                                    "euro_area",
                                    "nafta",
                                    "mercosur",
                                    "afta",
                                    "apec",
                                    "gcc",
                                    "cisfta",
                                    "emerging_markets",
                                    "itunes_app_store",
                                    "android_free_store",
                                    "android_paid_store"
                                  ],
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "customLocations": {
                                "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                                "items": {
                                  "properties": {
                                    "address": {
                                      "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                      "type": "string"
                                    },
                                    "distanceUnit": {
                                      "enum": [
                                        "mile",
                                        "kilometer"
                                      ],
                                      "type": "string"
                                    },
                                    "latitude": {
                                      "maximum": 90,
                                      "minimum": -90,
                                      "type": "number"
                                    },
                                    "longitude": {
                                      "maximum": 180,
                                      "minimum": -180,
                                      "type": "number"
                                    },
                                    "name": {
                                      "type": "string"
                                    },
                                    "radius": {
                                      "description": "Positive radius around the point.",
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "distanceUnit",
                                    "latitude",
                                    "longitude",
                                    "radius"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "neighborhoods": {
                                "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                                "items": {
                                  "properties": {
                                    "key": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "places": {
                                "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                                "items": {
                                  "properties": {
                                    "key": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "regions": {
                                "items": {
                                  "properties": {
                                    "key": {
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "zips": {
                                "items": {
                                  "properties": {
                                    "key": {
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          },
                          "gender": {
                            "description": "Restrict by gender. 'all' (default) targets everyone.",
                            "enum": [
                              "all",
                              "male",
                              "female"
                            ],
                            "type": "string"
                          },
                          "incomeTier": {
                            "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                            "enum": [
                              "top_5",
                              "top_10",
                              "top_10_25",
                              "top_25_50"
                            ],
                            "type": "string"
                          },
                          "industries": {
                            "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "interests": {
                            "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                            "items": {
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "jobFunctions": {
                            "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "languages": {
                            "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "metros": {
                            "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                            "items": {
                              "oneOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "properties": {
                                    "key": {
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                }
                              ]
                            },
                            "type": "array"
                          },
                          "seniorities": {
                            "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "skills": {
                            "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "userDevice": {
                            "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                            "items": {
                              "minLength": 1,
                              "type": "string"
                            },
                            "minItems": 1,
                            "type": "array"
                          },
                          "userOs": {
                            "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                            "items": {
                              "minLength": 1,
                              "type": "string"
                            },
                            "minItems": 1,
                            "type": "array"
                          },
                          "workEmployers": {
                            "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                            "items": {
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "workIndustries": {
                            "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                            "items": {
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "workPositions": {
                            "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                            "items": {
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": {
                        "enum": [
                          "saved_targeting"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "name",
                      "spec",
                      "type"
                    ],
                    "type": "object"
                  }
                ],
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID. Must start with act_ for Meta; bare platform id for others (Google customer id, X/TikTok/LinkedIn/Pinterest account id).",
                    "type": "string"
                  },
                  "adIds": {
                    "description": "pinterest_engagement: people who engaged with these ads. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "array"
                  },
                  "campaignIds": {
                    "description": "pinterest_engagement: people who engaged with these campaigns' ads. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "array"
                  },
                  "companies": {
                    "description": "Required for company_list audiences (LinkedIn only). Plain-text company rows for account targeting; each row needs at least one identifier. Not hashed: LinkedIn matches these against its own company graph.",
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "country": {
                    "description": "2-letter code, required for lookalike audiences",
                    "type": "string"
                  },
                  "customerFileSource": {
                    "description": "Data source declaration for GDPR compliance (customer_list only)",
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "engagementDomains": {
                    "description": "pinterest_engagement: people who engaged with Pins from these domains. The domain must be claimed on the Pinterest account or Pinterest rejects it.",
                    "type": "array"
                  },
                  "engagementSource": {
                    "description": "Required for meta_engagement audiences (Meta only): what people engaged with. `page` = a Facebook Page, `instagram` = an IG professional account, `video` = a video.",
                    "type": "string"
                  },
                  "engagementSources": {
                    "description": "Required for engagement audiences. Campaign URNs for the ad source types, organization URNs for pages and events. LinkedIn creates one rule per source, all sharing the same trigger and lookbackDays.",
                    "type": "array"
                  },
                  "engagementType": {
                    "description": "pinterest_engagement: limit to one engagement action.",
                    "type": "string"
                  },
                  "engagerType": {
                    "description": "pinterest_engagement: Pinterest's `engager_type`, passed through when set.",
                    "type": "integer"
                  },
                  "event": {
                    "description": "The event to match. Its meaning depends on the type: meta_engagement: the engagement event. Defaults per source (page → page_engaged, instagram → ig_business_profile_all, video → video_watched). Ignored when `rule` is provided.",
                    "type": "string"
                  },
                  "identityAuthorizedBcId": {
                    "description": "tiktok_engagement: required when identityType is BC_AUTH_TT.",
                    "type": "string"
                  },
                  "identityId": {
                    "description": "tiktok_engagement: the TikTok identity that owns the videos or business account. Required for organic_video, live_video and business_account.",
                    "type": "string"
                  },
                  "identityType": {
                    "description": "tiktok_engagement: type of `identityId`.",
                    "type": "string"
                  },
                  "lookbackDays": {
                    "description": "Required for engagement audiences. Rolling window.",
                    "type": "integer"
                  },
                  "matchRules": {
                    "description": "Required for website_retargeting audiences (LinkedIn only). Each rule is a URL pattern; a member who visits any matching page enters the segment.",
                    "type": "array"
                  },
                  "name": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "pinIds": {
                    "description": "pinterest_engagement: people who engaged with these Pins. At least one of engagementDomains, campaignIds, adIds or pinIds is required.",
                    "type": "array"
                  },
                  "pixelId": {
                    "description": "website: the Meta pixel, TikTok pixel, Pinterest tag or Reddit pixel id. Required on those four, rejected on Google.",
                    "type": "string"
                  },
                  "ratio": {
                    "description": "lookalike on Meta (0.01-0.20) and Pinterest (0.01-0.10, whole percents). Rejected on TikTok and Google.",
                    "type": "number"
                  },
                  "retentionDays": {
                    "description": "Required for website (Meta max 180, TikTok 7/14/30/60/90/180, Reddit max 90, Pinterest and Google max 540), meta_engagement (max 365) and tiktok_engagement (7/14/30/60/90/180; organic and live video and most business-account events only…",
                    "type": "integer"
                  },
                  "rule": {
                    "description": "Meta only (a 400 elsewhere). Optional raw Meta rule, replacing the one we build. Omit it for all visitors of `pixelId`, or use `urlContains` for the common page-match case.",
                    "type": "object"
                  },
                  "size": {
                    "description": "lookalike on TikTok and Google: audience breadth. Rejected on Meta and Pinterest.",
                    "type": "string"
                  },
                  "source": {
                    "description": "Required for tiktok_engagement: what people engaged with.",
                    "type": "string"
                  },
                  "sourceAudienceId": {
                    "description": "Required for lookalike audiences Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "sourceId": {
                    "description": "Required for meta_engagement: the Page / IG account / video id.",
                    "type": "string"
                  },
                  "sourceIds": {
                    "description": "tiktok_engagement: ad group / campaign ids for `ads`, video ids for `organic_video` and `live_video` (max 10). Required except for `business_account`.",
                    "type": "array"
                  },
                  "sourceType": {
                    "description": "Required for engagement audiences (LinkedIn only): what members engaged with: a video/leadgen/single-image ad campaign, a Company Page or an Event page.",
                    "type": "string"
                  },
                  "spec": {
                    "description": "The targeting spec to store.",
                    "type": "object"
                  },
                  "trigger": {
                    "description": "Required for engagement audiences. The action, validated by LinkedIn against `sourceType`.",
                    "type": "string"
                  },
                  "type": {
                    "enum": [
                      "customer_list",
                      "company_list",
                      "engagement",
                      "meta_engagement",
                      "tiktok_engagement",
                      "pinterest_engagement",
                      "website",
                      "website_retargeting",
                      "lookalike",
                      "saved_targeting"
                    ],
                    "type": "string"
                  },
                  "urlContains": {
                    "description": "website on Meta, TikTok and Google. Narrows the audience from all visitors to visitors of URLs containing this substring. Ignored when `rule` is supplied. A 400 on Pinterest, which only matches exact URLs.",
                    "type": "string"
                  }
                },
                "required": [
                  "name",
                  "type"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "audience": {
                      "type": "object"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Audience created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create custom audience",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_audience@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "85f35485598659cb66cafb188a6ac01b95842b8d2d1a9ba610dfea6c2e14b915"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_audiences",
          "method": "POST",
          "path": "/apis/v1/ads/audiences"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_audiences"
      }
    },
    "/apis/v1/ads/audiences/{audienceId}": {
      "delete": {
        "description": "Ad Audiences. Changes the ad account without starting or raising spend; audited. Removes a custom audience from its ad platform (archiving it where the platform does not delete). ### By platform Deleted: Meta, Google, TikTok, LinkedIn list and engagement segments, X, and Reddit. Archived (how those platforms remove them): Pinterest audiences and LinkedIn `website_retargeting` segments.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_audiences_audienceid",
        "parameters": [
          {
            "in": "path",
            "name": "audienceId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Audience deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete custom audience",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_audience@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "407de9eda77d39b0d632c107926b79af3916c252989d60cc9f5e077bb3a08f41"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_audiences_audienceid",
          "method": "DELETE",
          "path": "/apis/v1/ads/audiences/{audienceId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_audiences_audienceid"
      },
      "get": {
        "description": "Ad Audiences. Read only. Shows a custom audience's details, including its latest data from the ad platform when available. Returns the local audience record and fresh data from Meta (if available).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_audiences_audienceid",
        "parameters": [
          {
            "in": "path",
            "name": "audienceId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "audience": {
                      "type": "object"
                    },
                    "platformData": {
                      "description": "Fresh data from the platform API",
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Audience details"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get audience details",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_audience@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "54b914377989b39d6e3018207e26b2987bbbb5095c4faf8c7ba187ce1d306b9d"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_audiences_audienceid",
          "method": "GET",
          "path": "/apis/v1/ads/audiences/{audienceId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_audiences_audienceid"
      },
      "put": {
        "description": "Ad Audiences. Changes the ad account without starting or raising spend; audited. Renames or redescribes an audience, or replaces a saved targeting audience's rules; platform audience rules cannot change. ### `saved_targeting` audiences They accept `name`, `description`, and `spec`. Ads already created from a saved_targeting audience are unaffected: they snapshot the targeting at creation. ### Platform audiences (uploaded/website/lookalike)\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_audiences_audienceid",
        "parameters": [
          {
            "in": "path",
            "name": "audienceId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "description": "example",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "description": "At least one field is required.",
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "spec": {
                    "description": "Full replacement for the stored targeting spec.",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "audience": {
                      "type": "object"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Audience updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update an audience",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_audience@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "fd83e16a6925a0ebdb467cd13c0bf1e579498b811abd4f88835f038cf85fd759"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_audiences_audienceid",
          "method": "PUT",
          "path": "/apis/v1/ads/audiences/{audienceId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_audiences_audienceid"
      }
    },
    "/apis/v1/ads/audiences/{audienceId}/companies": {
      "post": {
        "description": "Ad Audiences. Changes the ad account without starting or raising spend; audited. Upload the company rows of a LinkedIn `company_list` audience (account-based marketing). LinkedIn-only, every other platform returns 422. The initial list is sent with `companies` on `POST /apis/v1/ads/audiences`; this endpoint is for every change after that. ### Send the full list every time\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_audiences_audienceid_companies",
        "parameters": [
          {
            "in": "path",
            "name": "audienceId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "companies": [
                  {
                    "domain": "example",
                    "name": "Winter launch"
                  }
                ],
                "connectionId": "adc_7f3k2m9q"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "companies": {
                    "description": "The complete company list. Each row needs at least one of name, domain, website or linkedinPageUrl.",
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "domain": {
                          "maxLength": 100,
                          "type": "string"
                        },
                        "linkedinPageUrl": {
                          "type": "string"
                        },
                        "name": {
                          "maxLength": 255,
                          "type": "string"
                        },
                        "website": {
                          "maxLength": 100,
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "maxItems": 300000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  }
                },
                "required": [
                  "companies"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "numReceived": {
                      "description": "Rows sent to LinkedIn. Matching happens asynchronously, so this is not the matched company count.",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Companies uploaded"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Replace audience companies",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.replace_ad_audience_companies@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "2440a781b24710c5dce0c77b432ac84b5eaf5f59f8f31a0729d6a5b2325a76aa"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_audiences_audienceid_companies",
          "method": "POST",
          "path": "/apis/v1/ads/audiences/{audienceId}/companies"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_audiences_audienceid_companies"
      }
    },
    "/apis/v1/ads/audiences/{audienceId}/users": {
      "delete": {
        "description": "Ad Audiences. Changes the ad account without starting or raising spend; audited. Removes customer emails (and phone numbers on Meta) from a Meta or Reddit customer list audience. Same body as `POST /apis/v1/ads/audiences/{audienceId}/users`: send plaintext rows, they are normalized and SHA256-hashed server-side exactly like an upload, so a row removes the person it added. Meta and Reddit only, customer_list only.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_audiences_audienceid_users",
        "parameters": [
          {
            "in": "path",
            "name": "audienceId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "users": [
                  {
                    "email": "example",
                    "phone": "example"
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "users": {
                    "items": {
                      "description": "Each user must have at least email or phone",
                      "properties": {
                        "email": {
                          "format": "email",
                          "type": "string"
                        },
                        "phone": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "maxItems": 10000,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "users"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "invalidEntrySamples": {
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "A sample of the rows Meta could not read, passed through as Meta returns it. Empty when every row was valid.",
                      "type": "object"
                    },
                    "message": {
                      "type": "string"
                    },
                    "numInvalid": {
                      "description": "Rows the platform could not read.",
                      "type": "integer"
                    },
                    "numReceived": {
                      "description": "Rows the platform received.",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Users removed"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove users from audience",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_users_from_ad_audience@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a61f1ea3c53882cc82d69b4e370315a418e1c2eef0b901501974c292f0d305e4"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_audiences_audienceid_users",
          "method": "DELETE",
          "path": "/apis/v1/ads/audiences/{audienceId}/users"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_audiences_audienceid_users"
      },
      "post": {
        "description": "Ad Audiences. Changes the ad account without starting or raising spend; audited. Uploads customer emails (and phone numbers on Meta) to a customer list audience, hashed before they are sent. Data is SHA256-hashed server-side before sending to the platform. Max 10,000 users per request. ### Per-platform behavior All platforms: email is used everywhere. Phone is used on Meta only (other platforms ignore it).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_audiences_audienceid_users",
        "parameters": [
          {
            "in": "path",
            "name": "audienceId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "users": [
                  {
                    "email": "example",
                    "phone": "example"
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "users": {
                    "items": {
                      "description": "Each user must have at least email or phone",
                      "properties": {
                        "email": {
                          "format": "email",
                          "type": "string"
                        },
                        "phone": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "maxItems": 10000,
                    "type": "array"
                  }
                },
                "required": [
                  "users"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "numInvalid": {
                      "description": "Rows the platform could not read. Returned on Meta, and on Reddit for rows without a valid email.",
                      "type": "integer"
                    },
                    "numReceived": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Users added"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Add users to audience",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.add_users_to_ad_audience@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "442d783f01ec1664a131b72792a4d406e31dab5d2032f767886fe757f64f425e"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_audiences_audienceid_users",
          "method": "POST",
          "path": "/apis/v1/ads/audiences/{audienceId}/users"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_audiences_audienceid_users"
      }
    },
    "/apis/v1/ads/bid-strategies": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists a Google Ads account's shared bid strategies with how many campaigns use each and how they performed. The bidding strategy report covers type, status, campaign count, clicks, cost, cost per conversion, impressions, average CPC and conversions over the date range (default last 30 days). ### Data source\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_bid_strategies",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Defaults to the account's connected customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Defaults to 30 days ago.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Defaults to today.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "When this data was fetched from Google. Null when it was never served from cache.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "currency": {
                      "description": "Account currency code; money fields are in this currency's units.",
                      "type": "string"
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "stale": {
                      "description": "True when Google's daily API quota was exhausted and this is the last successful fetch, not a live read.",
                      "type": "boolean"
                    },
                    "strategies": {
                      "items": {
                        "description": "A Google Ads portfolio bid strategy: a named bidding strategy shared across campaigns, with its R.130 report metrics over the queried date range.",
                        "properties": {
                          "averageCpc": {
                            "description": "Average CPC in the account's currency units.",
                            "type": "number"
                          },
                          "campaignCount": {
                            "description": "Number of campaigns currently attached.",
                            "type": "integer"
                          },
                          "clicks": {
                            "type": "integer"
                          },
                          "conversions": {
                            "type": "number"
                          },
                          "cost": {
                            "description": "Cost in the account's currency units (converted from micros).",
                            "type": "number"
                          },
                          "costPerConversion": {
                            "description": "Cost per conversion in the account's currency units.",
                            "type": "number"
                          },
                          "id": {
                            "description": "Numeric bid strategy id; pass as portfolioBidStrategyId or in the {strategyId} path.",
                            "type": "string"
                          },
                          "impressions": {
                            "type": "integer"
                          },
                          "name": {
                            "type": "string"
                          },
                          "status": {
                            "description": "ENABLED or REMOVED.",
                            "type": "string"
                          },
                          "targetCpa": {
                            "description": "Current target, in the account's currency units. Null for a ROAS-family type (TARGET_ROAS, MAXIMIZE_CONVERSION_VALUE), or a Maximize type with no target set. Pre-fills the edit form's target field.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "targetImpressionShare": {
                            "description": "Current target for a TARGET_IMPRESSION_SHARE strategy, null for every other type.",
                            "oneOf": [
                              {
                                "description": "Google only. Target impression share bidding (Search campaigns only): Google sets bids so the ads show in `location` for `percent` of eligible impressions.",
                                "properties": {
                                  "location": {
                                    "enum": [
                                      "ANYWHERE_ON_PAGE",
                                      "TOP_OF_PAGE",
                                      "ABSOLUTE_TOP_OF_PAGE"
                                    ],
                                    "type": "string"
                                  },
                                  "maxCpc": {
                                    "description": "Max CPC bid limit, in the account's currency units. Google requires it.",
                                    "exclusiveMinimum": 0,
                                    "type": "number"
                                  },
                                  "percent": {
                                    "description": "Target share of impressions, in percent (65 = 65%). Sent to Google as location_fraction_micros (1% = 10,000).",
                                    "exclusiveMinimum": 0,
                                    "maximum": 100,
                                    "type": "number"
                                  }
                                },
                                "required": [
                                  "location",
                                  "maxCpc",
                                  "percent"
                                ],
                                "type": "object"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "targetRoas": {
                            "description": "Current target as a decimal multiplier (2.0 = 2.0x). Null for a CPA-family type (TARGET_CPA, MAXIMIZE_CONVERSIONS), or a Maximize type with no target set.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "type": {
                            "enum": [
                              "TARGET_CPA",
                              "TARGET_ROAS",
                              "MAXIMIZE_CONVERSIONS",
                              "MAXIMIZE_CONVERSION_VALUE",
                              "TARGET_IMPRESSION_SHARE"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Portfolio bid strategies"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List portfolio bid strategies",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_bid_strategies@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "8f640a8ae4a553fa5567e582acb837df380f14711093f1ef9ec7118e21eae538"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_bid_strategies",
          "method": "GET",
          "path": "/apis/v1/ads/bid-strategies"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_bid_strategies"
      },
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates a portfolio bid strategy that sets what campaigns bid. Creates a Google Ads bid strategy that several campaigns can share, such as one target CPA or ROAS. Attach it to a campaign with `portfolioBidStrategyId` on POST /apis/v1/ads/create, PUT /apis/v1/ads/campaigns/{campaignId}, or PUT /apis/v1/ads/ad-sets/{adSetId}.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_bid_strategies",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch",
                "type": "TARGET_CPA"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Defaults to the account's connected customer.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "targetCpa": {
                    "description": "Required when type is TARGET_CPA, in the account's currency units.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "targetImpressionShare": {
                    "additionalProperties": false,
                    "description": "Required when type is TARGET_IMPRESSION_SHARE, and refused with any other type.",
                    "properties": {
                      "location": {
                        "enum": [
                          "ANYWHERE_ON_PAGE",
                          "TOP_OF_PAGE",
                          "ABSOLUTE_TOP_OF_PAGE"
                        ],
                        "type": "string"
                      },
                      "maxCpc": {
                        "description": "Max CPC bid limit, in the account's currency units. Google requires it.",
                        "exclusiveMinimum": 0,
                        "type": "number"
                      },
                      "percent": {
                        "description": "Target share of impressions, in percent (65 = 65%). Sent to Google as location_fraction_micros (1% = 10,000).",
                        "exclusiveMinimum": 0,
                        "maximum": 100,
                        "type": "number"
                      }
                    },
                    "required": [
                      "location",
                      "maxCpc",
                      "percent"
                    ],
                    "type": "object"
                  },
                  "targetRoas": {
                    "description": "Required when type is TARGET_ROAS; a multiplier (2.0 = 2.0x).",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "type": {
                    "enum": [
                      "TARGET_CPA",
                      "TARGET_ROAS",
                      "MAXIMIZE_CONVERSIONS",
                      "MAXIMIZE_CONVERSION_VALUE",
                      "TARGET_IMPRESSION_SHARE"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "name",
                  "type"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "strategy": {
                      "properties": {
                        "customerId": {
                          "type": "string"
                        },
                        "id": {
                          "description": "Numeric bid strategy id; pass as portfolioBidStrategyId or in the {strategyId} path.",
                          "type": "string"
                        },
                        "resourceName": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Bid strategy created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create portfolio bid strategy",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_bid_strategy@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "068111d0ac2fdfd8f14314471b0a64bd09273ed3790ca05da5c794c37bb83e08"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_bid_strategies",
          "method": "POST",
          "path": "/apis/v1/ads/bid-strategies"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_bid_strategies"
      }
    },
    "/apis/v1/ads/bid-strategies/{strategyId}": {
      "patch": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Changes a portfolio bid strategy's targets, and so what its campaigns bid. Renames a shared Google Ads bid strategy or changes its target CPA or ROAS. The strategy's status is output only on Google's side, so it cannot be changed here; remove a strategy in Google Ads. ### When to send `type` `type` is only needed alongside `targetCpa`/`targetRoas`, to disambiguate the field Google writes to: TARGET_CPA and MAXIMIZE_CONVERSIONS both take a target CPA.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_bid_strategies_strategyid",
        "parameters": [
          {
            "description": "Numeric Google Ads bid strategy id.",
            "in": "path",
            "name": "strategyId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Defaults to the account's connected customer.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "targetCpa": {
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "targetImpressionShare": {
                    "additionalProperties": false,
                    "description": "Retargets a TARGET_IMPRESSION_SHARE strategy; location, percent and maxCpc are all written.",
                    "properties": {
                      "location": {
                        "enum": [
                          "ANYWHERE_ON_PAGE",
                          "TOP_OF_PAGE",
                          "ABSOLUTE_TOP_OF_PAGE"
                        ],
                        "type": "string"
                      },
                      "maxCpc": {
                        "description": "Max CPC bid limit, in the account's currency units. Google requires it.",
                        "exclusiveMinimum": 0,
                        "type": "number"
                      },
                      "percent": {
                        "description": "Target share of impressions, in percent (65 = 65%). Sent to Google as location_fraction_micros (1% = 10,000).",
                        "exclusiveMinimum": 0,
                        "maximum": 100,
                        "type": "number"
                      }
                    },
                    "required": [
                      "location",
                      "maxCpc",
                      "percent"
                    ],
                    "type": "object"
                  },
                  "targetRoas": {
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "type": {
                    "enum": [
                      "TARGET_CPA",
                      "TARGET_ROAS",
                      "MAXIMIZE_CONVERSIONS",
                      "MAXIMIZE_CONVERSION_VALUE",
                      "TARGET_IMPRESSION_SHARE"
                    ],
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "strategy": {
                      "properties": {
                        "customerId": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Bid strategy updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update portfolio bid strategy",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_bid_strategy@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "f02c5b74f343fdcace6e551550a2135e5f257b24d61cf6fdc7ed9bbbd05068d0"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_bid_strategies_strategyid",
          "method": "PATCH",
          "path": "/apis/v1/ads/bid-strategies/{strategyId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_bid_strategies_strategyid"
      }
    },
    "/apis/v1/ads/boost": {
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Boosts a published post as an ad that spends the given budget. validateOnly=true checks the request without acting and needs no confirmation. Turns an already published post into a paid ad that keeps the post's likes and comments, creating the campaign around it. By default it provisions the whole hierarchy (campaign, ad set, ad). ### Attach shape (Meta) Send `adSetId` to put the ad under an EXISTING ad set instead, so that ad set keeps its learning phase. That ad set then owns `budget`, `schedule` and `targeting`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_boost",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_757082720485182",
                "budget": {
                  "amount": 2.61,
                  "type": "daily"
                },
                "callToAction": "WHATSAPP_MESSAGE",
                "connectionId": "adc_7f3k2m9q",
                "goal": "engagement",
                "name": "WhatsApp post boost",
                "platformPostId": "811889972008357_123456789",
                "status": "PAUSED",
                "whatsappPhoneNumber": "+12025550123"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID",
                    "type": "string"
                  },
                  "adSetId": {
                    "description": "Meta, or TikTok with `smartPlus: true`. Attach the boosted post to this existing ad set instead of creating a campaign. Meta: the ad set then owns budget, schedule and targeting; sending those too is a 400. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "adSetName": {
                    "description": "Exact name for the ad-group level this boost provisions. Omitted keeps the default ` - Ad Group`. Meta: ad set; TikTok, Pinterest, Google: ad group; X: line item; LinkedIn: the campaign under the campaign group.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "adSetStatus": {
                    "description": "Every platform, same semantics as POST /apis/v1/ads/create. Sets the switch of the new ad set alone and overrides `status` for it. Omitted, it follows `status`.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "adStatus": {
                    "description": "Request-side publish switch for `adStatus` on ad creation endpoints only (`status`, `campaignStatus` and `adSetStatus` carry their own inline ACTIVE/PAUSED enum there; the status-update endpoints are a separate lowercase `active`/`paused`…",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "attributionSpec": {
                    "description": "Meta only. Ad-set attribution windows, same shape as POST /apis/v1/ads/create.",
                    "items": {
                      "properties": {
                        "eventType": {
                          "enum": [
                            "CLICK_THROUGH",
                            "VIEW_THROUGH",
                            "ENGAGED_VIDEO_VIEW"
                          ],
                          "type": "string"
                        },
                        "windowDays": {
                          "enum": [
                            1,
                            7,
                            28
                          ],
                          "type": "integer"
                        }
                      },
                      "required": [
                        "eventType",
                        "windowDays"
                      ],
                      "type": "object"
                    },
                    "maxItems": 3,
                    "minItems": 1,
                    "type": "array"
                  },
                  "bidAmount": {
                    "description": "Deprecated: send it inside `platformSpecificData` instead (Meta today; TikTok's nested shape is planned). The flat field keeps working during the deprecation window; sending both shapes returns a 400.",
                    "type": "number"
                  },
                  "bidStrategy": {
                    "description": "Deprecated: send it inside `platformSpecificData` instead (Meta today; TikTok's nested shape is planned). The flat field keeps working during the deprecation window; sending both shapes returns a 400.",
                    "enum": [
                      "LOWEST_COST_WITHOUT_CAP",
                      "LOWEST_COST_WITH_BID_CAP",
                      "COST_CAP",
                      "LOWEST_COST_WITH_MIN_ROAS"
                    ],
                    "type": "string"
                  },
                  "bodies": {
                    "description": "Meta only. Extra primary-text options Meta rotates on the boosted post (asset_feed_spec.bodies with DEGREES_OF_FREEDOM). The post keeps its own text as one of the options. Works for Facebook posts and Instagram media.",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 5,
                    "minItems": 1,
                    "type": "array"
                  },
                  "budget": {
                    "description": "Alias of budgetAmount + budgetType, kept for existing callers",
                    "properties": {
                      "amount": {
                        "description": "Minimum varies: TikTok=$20, Pinterest=$5, others=$1",
                        "type": "number"
                      },
                      "type": {
                        "enum": [
                          "daily",
                          "lifetime"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "amount",
                      "type"
                    ],
                    "type": "object"
                  },
                  "budgetAmount": {
                    "description": "Budget in whole currency units, the same flat field as POST /apis/v1/ads/create. Required unless adSetId is set. Minimum varies: TikTok=$20, Pinterest=$5, others=$1",
                    "type": "number"
                  },
                  "budgetLevel": {
                    "description": "Meta only, same semantics as POST /apis/v1/ads/create: campaign = Advantage campaign budget (CBO), the budget and bid strategy sit on the campaign and the ad set inherits them. Default adset. Not allowed with adSetId.",
                    "enum": [
                      "adset",
                      "campaign"
                    ],
                    "type": "string"
                  },
                  "budgetType": {
                    "description": "Goes together with budgetAmount. lifetime requires schedule.endDate.",
                    "enum": [
                      "daily",
                      "lifetime"
                    ],
                    "type": "string"
                  },
                  "callToAction": {
                    "description": "CTA button label. Non-messaging CTAs require `linkUrl`. WHATSAPP_MESSAGE, MESSAGE_PAGE, and INSTAGRAM_MESSAGE do not require a URL and reject linkUrl.",
                    "type": "string"
                  },
                  "campaignName": {
                    "description": "Exact name for the campaign this boost provisions. Omitted keeps the default ` - Campaign`. Every platform: on LinkedIn it names the campaign group. Ignored on the Meta attach shape (`adSetId`), which creates no campaign.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "campaignStatus": {
                    "description": "Every platform, same semantics as POST /apis/v1/ads/create. Sets the switch of the new campaign alone (LinkedIn: the campaign group) and overrides `status` for it. When omitted, it follows `status`.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "creativeFeatures": {
                    "additionalProperties": {
                      "enum": [
                        "OPT_IN",
                        "OPT_OUT"
                      ],
                      "type": "string"
                    },
                    "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                    "type": "object"
                  },
                  "currency": {
                    "description": "ISO 4217 currency code matching the ad account's currency. Meta only.",
                    "maxLength": 3,
                    "minLength": 3,
                    "type": "string"
                  },
                  "destinationType": {
                    "description": "Meta only. Ad-set destination_type: where the click LANDS, as opposed to instagramAccountId which is who the ad runs as. Independent of plain link CTAs and their goal.",
                    "enum": [
                      "INSTAGRAM_PROFILE",
                      "WEBSITE",
                      "ON_AD",
                      "MESSENGER",
                      "WHATSAPP",
                      "INSTAGRAM_DIRECT"
                    ],
                    "type": "string"
                  },
                  "dsaBeneficiary": {
                    "description": "Legal entity that benefits from the ad. Required when targeting EU users (EU DSA, Article 26).",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "dsaPayor": {
                    "description": "Legal entity that pays for the ad. Can differ from `dsaBeneficiary` (for example, an agency paying for a client's ads). Same rules as `dsaBeneficiary`: required for EU targeting unless the ad account has a default payor.",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "endDate": {
                    "description": "Ad-set end time (ISO 8601). Required for lifetime budgets. Same field as on POST /apis/v1/ads/create. Maps to the ad set's `end_time` (on X, the line item's `end_time`; X campaigns carry no flight dates).",
                    "format": "date-time",
                    "type": "string"
                  },
                  "existingCampaignId": {
                    "description": "TikTok only. Create the ad group and the Spark ad under this existing TikTok campaign instead of creating a new campaign. The campaign keeps its own status and objective (the objective must fit `goal`). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "goal": {
                    "description": "Available goals vary by platform. Meta (Facebook/Instagram) and TikTok support all 7. LinkedIn supports all except app_promotion. X supports engagement, traffic, awareness, video_views, app_promotion.",
                    "enum": [
                      "engagement",
                      "traffic",
                      "awareness",
                      "video_views",
                      "lead_generation",
                      "conversions",
                      "app_promotion"
                    ],
                    "type": "string"
                  },
                  "identityId": {
                    "description": "TikTok only. The identity the ad runs as (the profile shown on the ad), from GET /apis/v1/ads/tiktok-identities. Default: the connected TikTok account's own identity.",
                    "type": "string"
                  },
                  "identityType": {
                    "description": "TikTok only. Type of identityId; resolved from the advertiser's identity list when omitted.",
                    "enum": [
                      "TT_USER",
                      "CUSTOMIZED_USER",
                      "BC_AUTH_TT"
                    ],
                    "type": "string"
                  },
                  "instagramAccountId": {
                    "description": "Meta only. Instagram identity the ad runs AS (creative.instagram_user_id), overriding the account linked to the Page. Live-verified against a Page-post creative.",
                    "type": "string"
                  },
                  "leadGenFormId": {
                    "description": "Lead Gen form ID to attach to the boosted ad's creative. REQUIRED when `goal` is `lead_generation`; ignored for other goals. Meta: the leadgen_forms ID (create one via POST /apis/v1/ads/lead-forms).",
                    "type": "string"
                  },
                  "lifetimeBudgetCap": {
                    "description": "X only (400 on another platform or on a lifetime budget). A lifetime total, in whole currency units, that caps a daily budget (budgetType daily). Must be at least budgetAmount.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "linkUrl": {
                    "description": "Website URL for non-messaging CTA buttons. Send it with `callToAction`. Omit for messaging boosts. Meta: adds a top-level `call_to_action` to the post-reference creative.",
                    "format": "uri",
                    "type": "string"
                  },
                  "locationTargetingType": {
                    "description": "Google only (400 elsewhere). Written on the campaign the boost creates.",
                    "enum": [
                      "presence",
                      "presence_or_interest"
                    ],
                    "type": "string"
                  },
                  "metaObjective": {
                    "description": "Meta only, with `goal: engagement` and without `adSetId` (400 otherwise).",
                    "enum": [
                      "OUTCOME_ENGAGEMENT"
                    ],
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "optimizationGoal": {
                    "description": "Ad-set optimization goal override. Meta, or TikTok with `goal: video_views`. TikTok: ENGAGED_VIEW (6-second Focused View, the default) or ENGAGED_VIEW_FIFTEEN (15-second views), both billed per view (CPV). Any other value is a 400.",
                    "type": "string"
                  },
                  "platformPostId": {
                    "description": "Platform post ID (alternative to postId). Reddit: the post id, with or without the `t3_` prefix. Meta: a Page post id (`_` or the bare post id) or an Instagram media id.",
                    "type": "string"
                  },
                  "platformSpecificData": {
                    "description": "Platform-specific options. The platform is derived from `connectionId`; sending options for a different platform returns a 400. LinkedIn (campaign bidding and delivery controls) and Meta (the bid trio) have options today.",
                    "oneOf": [
                      {
                        "additionalProperties": false,
                        "description": "LinkedIn-specific options for POST /apis/v1/ads/boost and POST /apis/v1/ads/create: campaign bidding and delivery controls, plus the LinkedIn-only creative formats on /apis/v1/ads/create. Unknown keys are rejected.",
                        "properties": {
                          "audienceExpansionEnabled": {
                            "description": "Enable LinkedIn audience expansion. Defaults to false.",
                            "type": "boolean"
                          },
                          "carousel": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Carousel ad with 2-10 image cards. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "cards": {
                                "items": {
                                  "additionalProperties": false,
                                  "properties": {
                                    "headline": {
                                      "description": "Card title. Falls back to the ad-level headline.",
                                      "type": "string"
                                    },
                                    "imageUrl": {
                                      "format": "uri",
                                      "type": "string"
                                    },
                                    "landingUrl": {
                                      "description": "Per-card click destination. LinkedIn requires one on every card; the ad-level `linkUrl` backfills cards that omit it.",
                                      "format": "uri",
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "imageUrl"
                                  ],
                                  "type": "object"
                                },
                                "maxItems": 10,
                                "minItems": 2,
                                "type": "array"
                              }
                            },
                            "required": [
                              "cards"
                            ],
                            "type": "object"
                          },
                          "connectedTelevisionOnly": {
                            "description": "Restrict delivery to Connected TV inventory.",
                            "type": "boolean"
                          },
                          "conversation": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Conversation Ad: a choose-your-path message tree delivered to the member's LinkedIn inbox. Messages are flat nodes wired by local ids. Each button either opens a url or leads to nextMessageId.",
                            "properties": {
                              "body": {
                                "description": "Optional intro body (HTML allowed).",
                                "type": "string"
                              },
                              "firstMessageId": {
                                "type": "string"
                              },
                              "footer": {
                                "description": "Terms shown at the bottom of the message.",
                                "type": "string"
                              },
                              "headline": {
                                "description": "Conversation headline. Defaults to the first message's first line.",
                                "type": "string"
                              },
                              "messages": {
                                "items": {
                                  "additionalProperties": false,
                                  "properties": {
                                    "buttons": {
                                      "items": {
                                        "additionalProperties": true,
                                        "type": "object"
                                      },
                                      "maxItems": 5,
                                      "minItems": 1,
                                      "type": "array"
                                    },
                                    "id": {
                                      "type": "string"
                                    },
                                    "text": {
                                      "maxLength": 500,
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "text"
                                  ],
                                  "type": "object"
                                },
                                "maxItems": 25,
                                "minItems": 1,
                                "type": "array"
                              },
                              "sender": {
                                "description": "Person or organization URN. Defaults to the authoring Company Page. The sender must be approved for the ad account first (Campaign Manager > Manage message ad senders) or LinkedIn rejects the create with SINMAIL_SENDER_NOT_APPROVED.",
                                "type": "string"
                              },
                              "subject": {
                                "description": "InMail subject shown in the inbox.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "firstMessageId",
                              "messages",
                              "subject"
                            ],
                            "type": "object"
                          },
                          "costType": {
                            "description": "Campaign cost model (billing event). Defaults to `CPM`. Required when `unitCost` is set so the manual bid applies to an explicit cost model.",
                            "enum": [
                              "CPM",
                              "CPC",
                              "CPV"
                            ],
                            "type": "string"
                          },
                          "creativeSelection": {
                            "description": "How LinkedIn rotates creatives within the campaign. Defaults to `OPTIMIZED`.",
                            "enum": [
                              "OPTIMIZED",
                              "ROUND_ROBIN"
                            ],
                            "type": "string"
                          },
                          "document": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Document ad rendered as an in-feed viewer. PDF, PPT or DOC up to 100MB. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "title": {
                                "description": "Document title.",
                                "type": "string"
                              },
                              "url": {
                                "format": "uri",
                                "type": "string"
                              }
                            },
                            "required": [
                              "title",
                              "url"
                            ],
                            "type": "object"
                          },
                          "event": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Promotes an existing LinkedIn Event; no headline needed. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "urn": {
                                "description": "LinkedIn Event URN, urn:li:event:N.",
                                "pattern": "^urn:li:event:\\d+$",
                                "type": "string"
                              }
                            },
                            "required": [
                              "urn"
                            ],
                            "type": "object"
                          },
                          "follower": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Dynamic Follower Ad promoting the Company Page. Supported goals: engagement, awareness. headline and description take exactly one of preApproved or custom. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "callToAction": {
                                "enum": [
                                  "VISIT_ORGANIZATION_COMPANY_PAGE",
                                  "VISIT_ORGANIZATION_LIFE_PAGE",
                                  "VISIT_ORGANIZATION_JOBS_PAGE",
                                  "VISIT_ORGANIZATION_CAREERS_PAGE"
                                ],
                                "type": "string"
                              },
                              "description": {
                                "additionalProperties": false,
                                "properties": {
                                  "custom": {
                                    "description": "Free text, reviewed by LinkedIn.",
                                    "type": "string"
                                  },
                                  "preApproved": {
                                    "description": "LinkedIn preset id, not reviewed. Example GET_LATEST_JOBS_AND_INDUSTRY_NEWS.",
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "headline": {
                                "additionalProperties": false,
                                "properties": {
                                  "custom": {
                                    "description": "Free text, reviewed by LinkedIn.",
                                    "type": "string"
                                  },
                                  "preApproved": {
                                    "description": "LinkedIn preset id, not reviewed. Example GROW_YOUR_BUSINESS_INSIGHTS.",
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "logoUrl": {
                                "format": "uri",
                                "type": "string"
                              },
                              "organizationName": {
                                "type": "string"
                              },
                              "showMemberProfilePhoto": {
                                "description": "Defaults to true.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "callToAction",
                              "description",
                              "headline"
                            ],
                            "type": "object"
                          },
                          "jobs": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Dynamic Jobs Ad promoting your open roles, personalized with the viewer's profile photo. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "buttonLabel": {
                                "additionalProperties": false,
                                "properties": {
                                  "custom": {
                                    "description": "Free text, reviewed by LinkedIn.",
                                    "type": "string"
                                  },
                                  "preApproved": {
                                    "description": "LinkedIn preset id, not reviewed. One of SEE_MORE_JOBS, VIEW_MORE, CAREERS_AT_COMPANY.",
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "headline": {
                                "additionalProperties": false,
                                "properties": {
                                  "custom": {
                                    "description": "Free text, reviewed by LinkedIn.",
                                    "type": "string"
                                  },
                                  "preApproved": {
                                    "description": "LinkedIn preset id, not reviewed. Example MEMBER_READY_FOR_YOUR_DREAM_JOB.",
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "logoUrl": {
                                "format": "uri",
                                "type": "string"
                              },
                              "organizationName": {
                                "type": "string"
                              },
                              "showMemberProfilePhoto": {
                                "description": "Defaults to true.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "buttonLabel",
                              "headline"
                            ],
                            "type": "object"
                          },
                          "offsiteDeliveryEnabled": {
                            "description": "Deliver on the LinkedIn Audience Network. Defaults to false.",
                            "type": "boolean"
                          },
                          "optimizationTargetType": {
                            "description": "Campaign `optimizationTargetType` (e.g. `MAX_CLICK`, `TARGET_COST_PER_CLICK`, `MAX_IMPRESSION`). Forwarded verbatim; LinkedIn validates compatibility with the objective and `costType`. Default when omitted, derived from the objective:",
                            "type": "string"
                          },
                          "spotlight": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Dynamic Spotlight Ad personalized with the viewer's profile photo. Supported goals: traffic, awareness.",
                            "properties": {
                              "backgroundImageUrl": {
                                "description": "Custom background. Replaces the description and the profile photo.",
                                "format": "uri",
                                "type": "string"
                              },
                              "callToAction": {
                                "description": "Button label text.",
                                "type": "string"
                              },
                              "description": {
                                "description": "Mutually exclusive with backgroundImageUrl.",
                                "type": "string"
                              },
                              "headline": {
                                "type": "string"
                              },
                              "landingUrl": {
                                "format": "uri",
                                "type": "string"
                              },
                              "logoUrl": {
                                "format": "uri",
                                "type": "string"
                              },
                              "organizationName": {
                                "type": "string"
                              },
                              "showMemberProfilePhoto": {
                                "description": "Defaults to true.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "callToAction",
                              "headline",
                              "landingUrl"
                            ],
                            "type": "object"
                          },
                          "textAd": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Classic right-rail Text Ad. The copy lives here; ad-level body and headline are not used. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "description": {
                                "maxLength": 75,
                                "type": "string"
                              },
                              "headline": {
                                "maxLength": 25,
                                "type": "string"
                              },
                              "imageUrl": {
                                "description": "Optional 100x100 image.",
                                "format": "uri",
                                "type": "string"
                              },
                              "landingUrl": {
                                "format": "uri",
                                "type": "string"
                              }
                            },
                            "required": [
                              "description",
                              "headline",
                              "landingUrl"
                            ],
                            "type": "object"
                          },
                          "thoughtLeader": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Sponsors an existing LinkedIn post (a share or ugcPost authored by your organization's Company Page) as the creative, keeping its commentary, author and engagement.",
                            "properties": {
                              "postUrn": {
                                "description": "LinkedIn share or ugcPost URN: urn:li:share:N or urn:li:ugcPost:N. Get it via \"Copy link to post\" on the target LinkedIn post. The URL contains -share- (share) or -ugcPost- (ugcPost), then the numeric id.",
                                "pattern": "^urn:li:(share|ugcPost):\\d+$",
                                "type": "string"
                              }
                            },
                            "required": [
                              "postUrn"
                            ],
                            "type": "object"
                          },
                          "unitCost": {
                            "description": "Manual bid in WHOLE account-currency units (e.g. 2.5 = $2.50). Requires `costType`. Omit for LinkedIn's automated (max delivery) bidding. LinkedIn enforces its own per-audience min/max bid bounds.",
                            "type": "number"
                          }
                        },
                        "type": "object"
                      },
                      {
                        "additionalProperties": false,
                        "description": "Meta (facebook/instagram) options for platformSpecificData on POST /apis/v1/ads/boost and /apis/v1/ads/create. Unknown keys are rejected, not dropped.",
                        "properties": {
                          "adSchedule": {
                            "description": "Dayparting on the ad set being created (Meta `adset_schedule` with `pacing_type: [\"day_parting\"]`). Change it later with `PUT /apis/v1/ads/ad-sets/{adSetId}`. A 400 with `param: platformSpecificData.adSchedule` when:",
                            "items": {
                              "additionalProperties": false,
                              "properties": {
                                "dayOfWeek": {
                                  "enum": [
                                    "MONDAY",
                                    "TUESDAY",
                                    "WEDNESDAY",
                                    "THURSDAY",
                                    "FRIDAY",
                                    "SATURDAY",
                                    "SUNDAY"
                                  ],
                                  "type": "string"
                                },
                                "endHour": {
                                  "description": "Must be after startHour. 24 is midnight at the end of the day.",
                                  "maximum": 24,
                                  "minimum": 1,
                                  "type": "integer"
                                },
                                "startHour": {
                                  "maximum": 23,
                                  "minimum": 0,
                                  "type": "integer"
                                },
                                "timezoneType": {
                                  "default": "USER",
                                  "description": "Meta `timezone_type`: USER runs the hours in each viewer's time zone, ADVERTISER in the ad account time zone.",
                                  "enum": [
                                    "USER",
                                    "ADVERTISER"
                                  ],
                                  "type": "string"
                                }
                              },
                              "required": [
                                "dayOfWeek",
                                "endHour",
                                "startHour"
                              ],
                              "type": "object"
                            },
                            "maxItems": 168,
                            "minItems": 1,
                            "type": "array"
                          },
                          "bidAmount": {
                            "description": "Whole currency units (USD: 5 = $5.00). Required when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP.",
                            "type": "number"
                          },
                          "bidStrategy": {
                            "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                            "enum": [
                              "LOWEST_COST_WITHOUT_CAP",
                              "LOWEST_COST_WITH_BID_CAP",
                              "COST_CAP",
                              "LOWEST_COST_WITH_MIN_ROAS"
                            ],
                            "type": "string"
                          },
                          "customerLifecycle": {
                            "additionalProperties": false,
                            "description": "Meta's Customer Lifecycle Strategy on a Sales ad set (Meta `ad_set_goal`). Rejected with 400 in adSetId attach mode: use PUT /apis/v1/ads/ad-sets/{adSetId} for an ad set that already exists.",
                            "properties": {
                              "engagedAudienceIds": {
                                "description": "Custom audience ids of people who engaged but have not bought. Required with new_customers_excluding_engaged, not allowed with the other strategies. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "existingCustomerAudienceIds": {
                                "description": "Custom audience ids that define your existing customers. Required with both new_customers strategies (Meta answers 400 subcode 1870251 without them); not allowed with all_customers. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "strategy": {
                                "description": "`all_customers` is \"Maximize conversions from all customers\". `new_customers` is \"Acquire new customers\" (excludes existing customers). `new_customers_excluding_engaged` also excludes people who engaged with you but have not bought yet.",
                                "enum": [
                                  "all_customers",
                                  "new_customers",
                                  "new_customers_excluding_engaged"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "strategy"
                            ],
                            "type": "object"
                          },
                          "dailyMinSpendTarget": {
                            "description": "Meta daily_min_spend_target on the ad set being created: the least it should spend per day, in whole currency units. A target, not a guarantee.",
                            "type": "number"
                          },
                          "lifetimeMinSpendTarget": {
                            "description": "Meta lifetime_min_spend_target: the lifetime-budget flavour of dailyMinSpendTarget, in whole currency units. Same rules and same rejections.",
                            "type": "number"
                          },
                          "roasAverageFloor": {
                            "description": "Decimal ROAS multiplier (2.0 = 2.0x). Required when bidStrategy is LOWEST_COST_WITH_MIN_ROAS; sending it without bidStrategy is a 400.",
                            "type": "number"
                          }
                        },
                        "type": "object"
                      }
                    ]
                  },
                  "postId": {
                    "type": "string"
                  },
                  "promoCodes": {
                    "description": "TikTok Smart+ Web Conversions only (requires `smartPlus: true`, goal `conversions`). Promo codes or offers TikTok highlights on the ad (Ads Manager's \"Add promo code or offer\"). A promo code needs shoppers to enter it at checkout.",
                    "items": {
                      "properties": {
                        "discountCurrency": {
                          "description": "ISO 4217; required for CASH.",
                          "type": "string"
                        },
                        "discountType": {
                          "enum": [
                            "PERCENTAGE",
                            "CASH"
                          ],
                          "type": "string"
                        },
                        "discountValue": {
                          "description": "PERCENTAGE: integer 1-100. CASH: amount greater than 0 in discountCurrency.",
                          "type": "number"
                        },
                        "minimumPurchaseCurrency": {
                          "description": "ISO 4217; required for SUBTOTAL.",
                          "type": "string"
                        },
                        "minimumPurchaseType": {
                          "enum": [
                            "QUANTITY",
                            "SUBTOTAL"
                          ],
                          "type": "string"
                        },
                        "minimumPurchaseValue": {
                          "description": "Required with minimumPurchaseType; QUANTITY is an integer >= 0, SUBTOTAL an amount > 0.",
                          "type": "number"
                        },
                        "promoCode": {
                          "description": "Code entered at checkout; omit for an automatic offer.",
                          "maxLength": 30,
                          "type": "string"
                        }
                      },
                      "required": [
                        "discountType",
                        "discountValue"
                      ],
                      "type": "object"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  },
                  "promotedObject": {
                    "description": "Meta, TikTok and Reddit. What the conversion ad set optimizes toward, so a boost of an existing organic post can run for a conversion instead of only engagement or traffic.",
                    "properties": {
                      "customConversionId": {
                        "description": "Meta only. Custom Conversion to optimize against, instead of pixelId + customEventType.",
                        "type": "string"
                      },
                      "customEventStr": {
                        "description": "Meta only. Pixel custom event name as it appears in Events Manager; requires customEventType OTHER.",
                        "type": "string"
                      },
                      "customEventType": {
                        "description": "Meta: standard pixel event (PURCHASE, LEAD, ...) or OTHER with customEventStr. TikTok: optimization_event code (e.g.",
                        "type": "string"
                      },
                      "pixelId": {
                        "description": "Meta Pixel id, TikTok Pixel (numeric id or the alphanumeric pixel code from Events Manager, resolved for you), or Reddit pixel id.",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "rawTargeting": {
                    "additionalProperties": true,
                    "description": "Meta only. A Meta-native targeting spec (e.g. `{ \"geo_locations\": { \"cities\": [{ \"key\": \"...\", \"radius\": 15, \"distance_unit\": \"kilometer\" }] } }`). Sent alone, it is forwarded unchanged.",
                    "type": "object"
                  },
                  "regionalRegulatedCategories": {
                    "description": "Meta only. Regional regulation categories required when the ad set targets certain countries (e.g.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "regionalRegulationIdentities": {
                    "additionalProperties": {
                      "type": [
                        "string",
                        "integer"
                      ]
                    },
                    "description": "Meta only. Verified identity IDs of the beneficiary and payer for each declared regionalRegulatedCategories value. Ignored when adSetId adds the ad to an existing ad set.",
                    "type": "object"
                  },
                  "rehostOnInstagramVideoRejection": {
                    "default": true,
                    "description": "Meta only (a 400 elsewhere). Controls the fallback when Meta refuses an existing Instagram video as the ad (subcode 1815279).",
                    "type": "boolean"
                  },
                  "roasAverageFloor": {
                    "description": "Deprecated: send it inside `platformSpecificData` instead (Meta today; TikTok's nested shape is planned). The flat field keeps working during the deprecation window; sending both shapes returns a 400.",
                    "type": "number"
                  },
                  "schedule": {
                    "description": "Alias of the top-level `startDate` / `endDate`, kept for existing callers. Sending both forms with differing values is a 400.",
                    "properties": {
                      "endDate": {
                        "description": "Alias of endDate, kept for existing callers",
                        "format": "date-time",
                        "type": "string"
                      },
                      "startDate": {
                        "description": "Alias of startDate, kept for existing callers",
                        "format": "date-time",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "smartPlus": {
                    "description": "TikTok only. Run the Spark post in a Smart+ campaign instead of a regular one: goal `conversions` = Smart+ Web Conversions, `lead_generation` = Smart+ Lead Generation. Rejected with a 400 on other platforms. Requires:",
                    "type": "boolean"
                  },
                  "smartTargeting": {
                    "description": "TikTok only (a 400 elsewhere). TikTok Smart Targeting on the ad group: `audience` is TikTok's `smart_audience_enabled`, `interestsBehaviors` its `smart_interest_behavior_enabled`.",
                    "properties": {
                      "audience": {
                        "description": "TikTok smart_audience_enabled.",
                        "type": "boolean"
                      },
                      "interestsBehaviors": {
                        "description": "TikTok smart_interest_behavior_enabled.",
                        "type": "boolean"
                      }
                    },
                    "type": "object"
                  },
                  "sparkAuthCode": {
                    "description": "TikTok-only. Spark Code (the creator's `auth_code`) authorizing cross-creator Spark Ads: the advertiser can boost a video owned by a DIFFERENT TikTok account. Maps to `auth_code` on the creative entry of /v2/ad/create/.",
                    "type": "string"
                  },
                  "sparkPosts": {
                    "description": "TikTok Smart+ only (requires `smartPlus: true`; a 400 on other platforms). Several Spark posts as creatives of ONE Smart+ ad, each with its own post code. Replaces `platformPostId` + `sparkAuthCode`.",
                    "items": {
                      "properties": {
                        "platformPostId": {
                          "description": "TikTok post (item) id.",
                          "type": "string"
                        },
                        "sparkAuthCode": {
                          "description": "That post's Spark code.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "platformPostId",
                        "sparkAuthCode"
                      ],
                      "type": "object"
                    },
                    "maxItems": 50,
                    "minItems": 1,
                    "type": "array"
                  },
                  "specialAdCategories": {
                    "description": "Meta only. Required for housing, employment, credit, or political ads.",
                    "items": {
                      "enum": [
                        "HOUSING",
                        "EMPLOYMENT",
                        "CREDIT",
                        "FINANCIAL_PRODUCTS_SERVICES",
                        "ISSUES_ELECTIONS_POLITICS",
                        "ONLINE_GAMBLING_AND_GAMING"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "specialAdCategoryCountry": {
                    "description": "Meta (metaads) only. 2-letter ISO country codes the special ad category applies to. Requires specialAdCategories to be set (400 otherwise).",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "startDate": {
                    "description": "Ad-set start time (ISO 8601, e.g. \"2026-06-10T09:00:00Z\"), mapped to the ad set's `start_time`. When omitted the ad starts delivering immediately.",
                    "format": "date-time",
                    "type": "string"
                  },
                  "status": {
                    "description": "Publish state of the created entities, on every platform. Omitted or ACTIVE publishes live (default). PAUSED pauses only the top-most object this boost creates and switches everything below it on:",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "targeting": {
                    "description": "Same geo/demographic fields as the `TargetingSpec` used by /apis/v1/ads/create. Geo keys (`regions`/`cities`/`zips`/`metros`) resolve via GET /apis/v1/ads/targeting/search?dimension=geo. Meta only: city radius and lat/lng `customLocations`.",
                    "properties": {
                      "advantage_audience": {
                        "description": "Meta only. 0 = disabled (default), 1 = enabled.",
                        "enum": [
                          0,
                          1
                        ],
                        "type": "integer"
                      },
                      "ageMax": {
                        "maximum": 65,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "maximum": 65,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits (both set together, Meta only).",
                        "items": {
                          "properties": {
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch. For a tighter catchment use customLocations (lat/lng).",
                              "type": "number"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO country codes. Required for TikTok boosts (TikTok's ad group requires location_ids); optional on other platforms.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations). No geo `key` lookup needed.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "gender": {
                        "description": "Applied on Meta, TikTok, Pinterest and Reddit. Ignored on Google, LinkedIn and X.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "interests": {
                        "description": "Interest objects from /apis/v1/ads/interests. Each must include id and name.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "name"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Meta locale ids (numeric), passed through as given. Reddit: language codes (e.g. `en`).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` from /apis/v1/ads/targeting/search?dimension=geo&geoType=region.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "tracking": {
                    "description": "Meta only, except `pixelId`, which also picks the Reddit pixel of the new ad group (`promotedObject.pixelId` wins when both are sent). Tracking specs (pixel, URL tags).",
                    "properties": {
                      "pixelId": {
                        "type": "string"
                      },
                      "urlTags": {
                        "description": "URL parameters appended to the ad link, rendered as `key=value` pairs joined with `&`.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "value": {
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "validateOnly": {
                    "default": false,
                    "description": "Meta only (facebook, instagram and Meta ads connections). Returns 200 with the same body as a validateOnly POST /apis/v1/ads/create (`validateOnly`, `results` per node, `message`).",
                    "type": "boolean"
                  },
                  "whatsappPhoneNumber": {
                    "description": "Meta WhatsApp only. E.164 number already paired with the Page. Omit to use the default pairing. Requires WHATSAPP_MESSAGE callToAction. Stored as creative.whatsappPhoneNumber on the ad.",
                    "pattern": "^\\+[1-9]\\d{6,14}$",
                    "type": "string"
                  },
                  "workflowId": {
                    "description": "Meta messaging boosts only (callToAction MESSAGE_PAGE, WHATSAPP_MESSAGE or INSTAGRAM_MESSAGE). A workflow in the account's profile, started in the conversation a click on the ad opens. Stored on the ad.",
                    "pattern": "^[a-fA-F0-9]{24}$",
                    "type": "string"
                  }
                },
                "required": [
                  "adAccountId",
                  "goal",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "results": {
                      "items": {
                        "properties": {
                          "node": {
                            "enum": [
                              "campaign",
                              "adSet",
                              "creative",
                              "ad"
                            ],
                            "type": "string"
                          },
                          "reason": {
                            "description": "Why the node was skipped (it already exists with adSetId), why Meta could not dry-run it (on unverified), or what the dry run could not check (on validated).",
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "validated",
                              "skipped",
                              "unverified"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "validateOnly": {
                      "description": "Always true in a validate-only response.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "validateOnly dry-run passed (Meta), nothing was created"
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ad": {
                      "properties": {
                        "_id": {
                          "type": "string"
                        },
                        "adSetName": {
                          "type": "string"
                        },
                        "adType": {
                          "enum": [
                            "boost",
                            "standalone"
                          ],
                          "type": "string"
                        },
                        "bidAmount": {
                          "description": "Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). Meta: `bid_amount` on the ad set (smallest-denomination int, decoded here).",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "bidStrategy": {
                          "anyOf": [
                            {
                              "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                              "enum": [
                                "LOWEST_COST_WITHOUT_CAP",
                                "LOWEST_COST_WITH_BID_CAP",
                                "COST_CAP",
                                "LOWEST_COST_WITH_MIN_ROAS"
                              ],
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Ad-set bid strategy (overrides campaign level on Meta). Populated for Meta and TikTok."
                        },
                        "budget": {
                          "properties": {
                            "amount": {
                              "type": "number"
                            },
                            "daily": {
                              "description": "LinkedIn and X only. The daily budget (LinkedIn: the parent campaign's `dailyBudget`; X: the line item's, or the campaign's when the line item has none).",
                              "type": "number"
                            },
                            "lifetime": {
                              "description": "LinkedIn and X only. The lifetime total (LinkedIn: the parent campaign's `totalBudget`; X: `total_budget_amount_local_micro`, for example the `lifetimeBudgetCap` of a boost), readable even when a daily budget is also set.",
                              "type": "number"
                            },
                            "pacing": {
                              "description": "LinkedIn only. The campaign's `pacingStrategy`: how fast LinkedIn may spend the budget. Typically LINEAR or ACCELERATED; the list is open.",
                              "type": "string"
                            },
                            "type": {
                              "enum": [
                                "daily",
                                "lifetime"
                              ],
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "campaignName": {
                          "type": "string"
                        },
                        "configuredStatus": {
                          "description": "The ad's own on/off switch as configured on the platform, independent of its parents. An ACTIVE ad under a paused ad set or campaign still reads ACTIVE here while `status` reads `paused`. Sources: Meta: `configured_status`.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "costType": {
                          "description": "LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn, refreshed on every sync rather than echoing what was passed on create. `null` for non-LinkedIn ads. `CPM`: cost per thousand impressions.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "createdAt": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "creative": {
                          "description": "Platform-specific creative data. Fields vary by platform.",
                          "properties": {
                            "adFormat": {
                              "description": "LinkedIn only. The LinkedIn ad format, in LinkedIn's own vocabulary: STANDARD_UPDATE, SINGLE_VIDEO, CAROUSEL, NATIVE_DOCUMENT, EVENT, TEXT_AD, SPOTLIGHT, FOLLOW_COMPANY, JOBS, SPONSORED_INMAILS and others.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "assetGroup": {
                              "description": "Google Performance Max creative assets. At least one description must be 60 characters or fewer. Texts within each list must be distinct.",
                              "properties": {
                                "businessName": {
                                  "maxLength": 25,
                                  "minLength": 1,
                                  "type": "string"
                                },
                                "descriptions": {
                                  "description": "At least one description must be 60 characters or fewer.",
                                  "items": {
                                    "maxLength": 90,
                                    "minLength": 1,
                                    "type": "string"
                                  },
                                  "maxItems": 5,
                                  "minItems": 2,
                                  "type": "array",
                                  "uniqueItems": true
                                },
                                "finalUrl": {
                                  "description": "Required destination URL.",
                                  "format": "uri",
                                  "pattern": "^https?://",
                                  "type": "string"
                                },
                                "headlines": {
                                  "items": {
                                    "maxLength": 30,
                                    "minLength": 1,
                                    "type": "string"
                                  },
                                  "maxItems": 15,
                                  "minItems": 3,
                                  "type": "array",
                                  "uniqueItems": true
                                },
                                "images": {
                                  "additionalProperties": true,
                                  "description": "Public HTTP(S) image URLs. GIF, JPEG or PNG, at most 5120 KB per image. Google validates dimensions and aspect ratios.",
                                  "type": "object"
                                },
                                "longHeadline": {
                                  "maxLength": 90,
                                  "minLength": 1,
                                  "type": "string"
                                },
                                "name": {
                                  "description": "Defaults to the request name.",
                                  "maxLength": 128,
                                  "minLength": 1,
                                  "type": "string"
                                },
                                "youtubeVideoId": {
                                  "description": "Optional existing YouTube video id. Google can generate video when omitted. Video uploads and arbitrary video URLs are not supported.",
                                  "pattern": "^[A-Za-z0-9_-]{11}$",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "businessName",
                                "descriptions",
                                "finalUrl",
                                "headlines",
                                "images",
                                "longHeadline"
                              ],
                              "type": "object"
                            },
                            "assetGroupResourceName": {
                              "description": "Google resource name of the created Performance Max asset group.",
                              "type": "string"
                            },
                            "assetResourceName": {
                              "description": "Google Display only. Resource name of the landscape marketing image asset (`creative.imageUrl`), for example customers/1234567890/assets/123.",
                              "type": "string"
                            },
                            "assets": {
                              "description": "Google Display only. Native Google asset resource name of each image on the responsive display ad, keyed by Google's image role.",
                              "properties": {
                                "marketingImages": {
                                  "description": "Landscape (1.91:1) marketing images. The first item matches `assetResourceName`.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "squareMarketingImages": {
                                  "description": "Square (1:1) marketing images.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "bodies": {
                              "description": "Meta: every primary text variation of the creative (`asset_feed_spec.bodies`), the same shape as the `bodies` create input. Present only with 2 or more texts; a single text is `body`.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "body": {
                              "description": "Ad copy/text",
                              "type": "string"
                            },
                            "callToAction": {
                              "description": "Meta: the call to action type (`call_to_action.type`, or the first `asset_feed_spec.call_to_action_types` entry), e.g. LEARN_MORE or SIGN_UP.",
                              "type": "string"
                            },
                            "carouselCards": {
                              "description": "Meta only today. The carousel's cards in display order, one per Meta `link_data.child_attachments` entry, using the same field names as the `carouselCards` create input. Absent on non-carousel ads and other platforms.",
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "type": "array"
                            },
                            "catalog": {
                              "properties": {
                                "format": {
                                  "description": "object_story_spec.template_data.format_option, from catalogFormat.",
                                  "enum": [
                                    "single_image",
                                    "carousel_images_multi_items",
                                    "carousel_images_single_item",
                                    "carousel_slideshows"
                                  ],
                                  "type": "string"
                                },
                                "formatTransformationSpec": {
                                  "description": "The format_transformation_spec sent on the creative, as Meta's raw objects. Present for single_image.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "productSetId": {
                                  "description": "The creative's product_set_id.",
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "creativeFeatures": {
                              "additionalProperties": {
                                "enum": [
                                  "OPT_IN",
                                  "OPT_OUT"
                                ],
                                "type": "string"
                              },
                              "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                              "type": "object"
                            },
                            "creativeId": {
                              "description": "Meta ad creative id backing this ad, refreshed from Meta on every sync. Reusable via existingCreativeId on POST /apis/v1/ads/create, and readable raw through GET /apis/v1/ads/creatives/{creativeId}.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "description": {
                              "description": "Meta: the creative's description under the title (`link_data.description`, `video_data.link_description`, or the first `asset_feed_spec.descriptions` entry).",
                              "type": "string"
                            },
                            "descriptions": {
                              "description": "Google RSA: the description assets as objects (2 to 4). Meta: every description variation of the creative (`asset_feed_spec.descriptions`) as strings, the same shape as the `descriptions` create input.",
                              "items": {
                                "oneOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "additionalProperties": true,
                                    "type": "object"
                                  }
                                ]
                              },
                              "maxItems": 4,
                              "type": "array"
                            },
                            "effectiveInstagramMediaId": {
                              "description": "Meta `effective_instagram_media_id`, the Instagram media ID of the boosted post the ad's engagement lives on. Pass to GET /apis/v1/ads?effectiveInstagramMediaId= to map a Business-Manager-visible IG post back to this ad.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "effectiveObjectStoryId": {
                              "description": "Meta `effective_object_story_id`, the `{pageId}_{postId}` of the Facebook post the ad's engagement (comments) lives on.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "finalUrls": {
                              "description": "Google RSA only. Replaces final URLs. Omitted lists stay unchanged.",
                              "items": {
                                "format": "uri",
                                "type": "string"
                              },
                              "minItems": 1,
                              "type": "array"
                            },
                            "googleDescription": {
                              "description": "Google Ads description",
                              "type": "string"
                            },
                            "googleHeadline": {
                              "description": "Google Ads headline",
                              "type": "string"
                            },
                            "headline": {
                              "description": "Meta: the creative's title (`link_data.name`, `video_data.title`, or the first `asset_feed_spec.titles` entry). Absent when the creative has none.",
                              "type": "string"
                            },
                            "headlines": {
                              "description": "Google RSA: the headline assets as objects (3 to 15). Meta: every title variation of the creative (`asset_feed_spec.titles`) as strings, the same shape as the `headlines` create input.",
                              "items": {
                                "oneOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "additionalProperties": true,
                                    "type": "object"
                                  }
                                ]
                              },
                              "maxItems": 15,
                              "type": "array"
                            },
                            "imageHash": {
                              "description": "Meta: the ad image hash (`image_hash`), reusable as `imageHash` on POST /apis/v1/ads/create within the same ad account. `thumbnailUrl` and `mediaUrls` carry its stable full resolution permalink when Meta resolves it.",
                              "type": "string"
                            },
                            "imageUrl": {
                              "description": "Alternative image URL",
                              "type": "string"
                            },
                            "instagramPermalinkUrl": {
                              "description": "Meta `instagram_permalink_url`, the public Instagram post URL of the boosted media.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "instagramUserId": {
                              "description": "Meta `instagram_user_id`, the Instagram-scoped business ID that owns the boosted media.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "instagramVideoFallback": {
                              "description": "Meta only. `instagram_video_reuploaded`: the video was copied into the ad account, and the ad still references the original post.",
                              "properties": {
                                "kind": {
                                  "enum": [
                                    "instagram_video_reuploaded",
                                    "instagram_video_rehosted_copy"
                                  ],
                                  "type": "string"
                                },
                                "linkedToOriginalPost": {
                                  "description": "True when the ad still references the original Instagram post and keeps its engagement.",
                                  "type": "boolean"
                                },
                                "platformError": {
                                  "additionalProperties": true,
                                  "description": "Meta's original refusal.",
                                  "type": "object"
                                },
                                "videoId": {
                                  "description": "instagram_video_reuploaded: the copy in the ad account video library (possibly one made by an earlier boost of the same media, reused).",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "kind",
                                "linkedToOriginalPost",
                                "platformError",
                                "videoId"
                              ],
                              "type": "object"
                            },
                            "isServing": {
                              "description": "LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign.",
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "leadGenFormId": {
                              "description": "Meta: the instant form the call to action opens (`call_to_action.value.lead_gen_form_id`, or the asset feed's `call_to_actions` on a dynamic creative), the same value as the `leadGenFormId` create input. Absent on ads without a lead form.",
                              "type": "string"
                            },
                            "linkUrl": {
                              "description": "Destination URL",
                              "type": "string"
                            },
                            "mediaUrls": {
                              "description": "All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts).",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "objectStoryId": {
                              "description": "Meta creative `object_story_id` (the SHARE reference). Frequently absent, because Meta omits it for SHARE creatives. Use effectiveObjectStoryId instead.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "objectType": {
                              "description": "Meta creative object_type (e.g. SHARE, VIDEO, PRIVACY_CHECK_FAIL, POST_DELETED). Use this to render state-aware previews: when Meta moderation strips image/video fields, only thumbnailUrl at 64x64 is available.",
                              "type": "string"
                            },
                            "pageId": {
                              "description": "Facebook Page backing the creative (Meta only). What the `pageId` filter on /apis/v1/ads, /apis/v1/ads/campaigns and /apis/v1/ads/tree matches against. Absent for non-Meta ads and rare Meta creatives with no page signal.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "pinterestDescription": {
                              "type": "string"
                            },
                            "pinterestImageUrl": {
                              "type": "string"
                            },
                            "pinterestTitle": {
                              "type": "string"
                            },
                            "servingHoldReasons": {
                              "description": "LinkedIn only. Why this specific creative is not being served. Empty when it is serving.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "thumbnailUrl": {
                              "description": "Primary thumbnail/image URL",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "urlTags": {
                              "description": "Meta: the creative's `url_tags` query string appended to the destination URL.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "videoId": {
                              "description": "Meta video ID for VIDEO-type ads. Null for non-video ads. Callers that need an embeddable MP4 can call GET /{videoId}?fields=source with the page access token.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "videoUrl": {
                              "description": "Null for non-video ads.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "whatsappPhoneNumber": {
                              "description": "Explicit E.164 WhatsApp number supplied when creating a Meta boost or messaging ad. Absent when omitted by the caller or on older records.",
                              "type": "string"
                            },
                            "youtubeVideoIds": {
                              "description": "Google only. YouTube video ids behind a Video campaign ad (video and responsive video ads) or a Demand Gen video ad, same id as `youtubeVideoId` on Performance Max asset groups.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "creativeType": {
                          "description": "Creative format, classified from the media the creative carries. `null` when the creative carries no media to classify. An unsynced creative and a genuine text-only ad are indistinguishable, so neither is guessed at.",
                          "enum": [
                            "carousel",
                            "video",
                            "document",
                            "image",
                            null
                          ],
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "goal": {
                          "description": "Available goals vary by platform:",
                          "enum": [
                            "engagement",
                            "traffic",
                            "awareness",
                            "video_views",
                            "lead_generation",
                            "lead_conversion",
                            "conversions",
                            "app_promotion",
                            "catalog_sales",
                            "page_likes",
                            "page_visits",
                            "job_applicants"
                          ],
                          "type": "string"
                        },
                        "isExternal": {
                          "description": "True for ads synced from platform ad managers",
                          "type": "boolean"
                        },
                        "metrics": {
                          "anyOf": [
                            {
                              "properties": {
                                "actionValues": {
                                  "additionalProperties": {
                                    "type": "number"
                                  },
                                  "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                  "type": "object"
                                },
                                "actions": {
                                  "additionalProperties": {
                                    "type": "integer"
                                  },
                                  "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                  "type": "object"
                                },
                                "allConversions": {
                                  "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                  "type": "number"
                                },
                                "clicks": {
                                  "type": "integer"
                                },
                                "conversions": {
                                  "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                  "type": "number"
                                },
                                "costPerAction": {
                                  "additionalProperties": {
                                    "type": "number"
                                  },
                                  "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                  "type": "object"
                                },
                                "costPerConversion": {
                                  "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                  "type": "number"
                                },
                                "costPerThruplay": {
                                  "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                  "type": "number"
                                },
                                "cpc": {
                                  "description": "Cost per click",
                                  "type": "number"
                                },
                                "cpm": {
                                  "description": "Cost per 1000 impressions",
                                  "type": "number"
                                },
                                "ctr": {
                                  "description": "Click-through rate (%)",
                                  "type": "number"
                                },
                                "engagement": {
                                  "type": "integer"
                                },
                                "engagementBreakdown": {
                                  "description": "The single `engagement` total, split into the interactions behind it.",
                                  "properties": {
                                    "comments": {
                                      "description": "Comments on the ad's post.",
                                      "type": "integer"
                                    },
                                    "linkClicks": {
                                      "description": "Attributed link clicks (`link_click`). This is the attribution-window count, which differs from the in-session count in the sibling `inlineLinkClicks` field.",
                                      "type": "integer"
                                    },
                                    "pageEngagement": {
                                      "description": "Meta's own page-engagement total (`page_engagement`). Meta-only.",
                                      "type": "integer"
                                    },
                                    "pageLikes": {
                                      "description": "New Page likes attributed to the ad (`like`).",
                                      "type": "integer"
                                    },
                                    "postEngagement": {
                                      "description": "Meta's own post-engagement total (`post_engagement`). Meta-only.",
                                      "type": "integer"
                                    },
                                    "reactions": {
                                      "description": "Reactions on the ad's post (`post_reaction`). For TikTok these are its paid likes.",
                                      "type": "integer"
                                    },
                                    "saves": {
                                      "description": "Saves of the ad's post (`onsite_conversion.post_save`).",
                                      "type": "integer"
                                    },
                                    "shares": {
                                      "description": "Shares of the ad's post. Meta reports these under the action type literally named `post`; TikTok under `share`.",
                                      "type": "integer"
                                    },
                                    "videoViews": {
                                      "description": "Video views, from the `video_view` action. Meta counts a 3-second view; LinkedIn's own `videoViews` threshold (2 continuous seconds, or 25% of the video) lands under the same key, so compare across platforms with care.",
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "funnel": {
                                  "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                  "properties": {
                                    "appInstalls": {
                                      "description": "Mobile app installs attributed to the ad.",
                                      "type": "integer"
                                    },
                                    "cartAdds": {
                                      "description": "Adds to cart (Meta `AddToCart` pixel event).",
                                      "type": "integer"
                                    },
                                    "checkoutsInitiated": {
                                      "description": "Checkouts started (Meta `InitiateCheckout` pixel event).",
                                      "type": "integer"
                                    },
                                    "contentViews": {
                                      "description": "Content views (Meta `ViewContent` pixel event).",
                                      "type": "integer"
                                    },
                                    "landingPageViews": {
                                      "description": "Landing page views: the visitor actually loaded the destination, unlike a link click. Meta `landing_page_view`.",
                                      "type": "integer"
                                    },
                                    "leads": {
                                      "description": "Leads, from either the website pixel or an instant form, whichever the ad uses.",
                                      "type": "integer"
                                    },
                                    "messagingConversationsStarted": {
                                      "description": "Messaging conversations started within 7 days, the headline metric for click-to-WhatsApp and click-to-Messenger ads.",
                                      "type": "integer"
                                    },
                                    "messagingFirstReplies": {
                                      "description": "Messaging threads where the person sent a first reply.",
                                      "type": "integer"
                                    },
                                    "paymentInfoAdds": {
                                      "description": "Payment details added at checkout (Meta `AddPaymentInfo` pixel event).",
                                      "type": "integer"
                                    },
                                    "purchases": {
                                      "description": "Purchases. Pair with `purchaseValue` for revenue.",
                                      "type": "integer"
                                    },
                                    "registrationsCompleted": {
                                      "description": "Completed registrations (Meta `CompleteRegistration` pixel event).",
                                      "type": "integer"
                                    },
                                    "searches": {
                                      "description": "On-site searches (Meta `Search` pixel event).",
                                      "type": "integer"
                                    },
                                    "wishlistAdds": {
                                      "description": "Adds to wishlist (Meta `AddToWishlist` pixel event).",
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "impressions": {
                                  "type": "integer"
                                },
                                "inlineLinkClickCtr": {
                                  "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                  "type": "number"
                                },
                                "inlineLinkClicks": {
                                  "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                  "type": "integer"
                                },
                                "lastSyncedAt": {
                                  "description": "Present on individual ads only, not on campaign aggregations",
                                  "format": "date-time",
                                  "type": "string"
                                },
                                "outboundClicks": {
                                  "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                  "type": "integer"
                                },
                                "outboundClicksCtr": {
                                  "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                  "type": "number"
                                },
                                "purchaseValue": {
                                  "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                  "type": "number"
                                },
                                "reach": {
                                  "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                  "type": "integer"
                                },
                                "roas": {
                                  "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                  "type": "number"
                                },
                                "spend": {
                                  "type": "number"
                                },
                                "uniqueClicks": {
                                  "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                  "type": "integer"
                                },
                                "uniqueCtr": {
                                  "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                  "type": "number"
                                },
                                "video2SecWatchedActions": {
                                  "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                  "type": "integer"
                                },
                                "video30SecWatchedActions": {
                                  "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                  "type": "integer"
                                },
                                "video6SecFocusedViews": {
                                  "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                  "type": "integer"
                                },
                                "video6SecWatchedActions": {
                                  "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                  "type": "integer"
                                },
                                "videoAvgTimeWatchedActions": {
                                  "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                  "type": "number"
                                },
                                "videoP100WatchedActions": {
                                  "description": "Views reaching 100% of the video's length.",
                                  "type": "integer"
                                },
                                "videoP25WatchedActions": {
                                  "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                  "type": "integer"
                                },
                                "videoP50WatchedActions": {
                                  "description": "Views reaching 50% of the video's length.",
                                  "type": "integer"
                                },
                                "videoP75WatchedActions": {
                                  "description": "Views reaching 75% of the video's length.",
                                  "type": "integer"
                                },
                                "videoP95WatchedActions": {
                                  "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                  "type": "integer"
                                },
                                "videoPlayActions": {
                                  "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                  "type": "integer"
                                },
                                "videoThruplayWatchedActions": {
                                  "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "name": {
                          "type": "string"
                        },
                        "optimizationGoal": {
                          "description": "What the delivery system optimizes for, at ad-set level. The value space depends on `platform`: Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS).",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platform": {
                          "enum": [
                            "facebook",
                            "instagram",
                            "tiktok",
                            "linkedin",
                            "pinterest",
                            "google",
                            "twitter",
                            "openai",
                            "reddit",
                            "microsoft"
                          ],
                          "type": "string"
                        },
                        "platformAdAccountId": {
                          "type": "string"
                        },
                        "platformAdAccountName": {
                          "description": "Human-readable advertiser/account name (Meta `AdAccount.name`, TikTok `advertiser_name`, LinkedIn / X / Pinterest equivalents). Refreshed every sync so platform-side renames propagate within one cycle.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platformAdId": {
                          "type": "string"
                        },
                        "platformAdSetId": {
                          "type": "string"
                        },
                        "platformCampaignId": {
                          "type": "string"
                        },
                        "platformCreatedAt": {
                          "description": "Platform-reported creation timestamp (Meta `created_time`, TikTok `create_time`). Read this field to sort or filter by when the ad was actually created on the platform.",
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platformObjective": {
                          "description": "The platform's own campaign objective, verbatim, alongside the normalized `goal` it maps to. The mapping is many-to-one, so `goal` alone cannot be mapped back to it. Meta: campaign `objective` (e.g.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "promotedObject": {
                          "description": "Meta promoted object containing conversion event details. Structure varies by objective. Only present for Meta ads.",
                          "properties": {
                            "application_id": {
                              "description": "Facebook app ID",
                              "type": "string"
                            },
                            "custom_event_type": {
                              "description": "Conversion event type (e.g. PURCHASE, LEAD, COMPLETE_REGISTRATION, ADD_TO_CART)",
                              "type": "string"
                            },
                            "page_id": {
                              "description": "Facebook page ID",
                              "type": "string"
                            },
                            "pixel_id": {
                              "description": "Meta pixel ID",
                              "type": "string"
                            },
                            "product_set_id": {
                              "description": "Product catalog set ID",
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "rejectionReason": {
                          "type": "string"
                        },
                        "reviewStatus": {
                          "description": "Platform review state of this ad, independent of delivery `status` / `configuredStatus`. Absent when the platform reports no review signal.",
                          "enum": [
                            "in_review",
                            "approved",
                            "rejected",
                            "with_issues"
                          ],
                          "type": "string"
                        },
                        "roasAverageFloor": {
                          "description": "Minimum ROAS as a decimal multiplier (2.0 = 2.0x ROAS). Populated when bidStrategy is `LOWEST_COST_WITH_MIN_ROAS`.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "schedule": {
                          "description": "Delivery window as UTC instants.",
                          "properties": {
                            "endDate": {
                              "format": "date-time",
                              "type": "string"
                            },
                            "startDate": {
                              "format": "date-time",
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "servingStatuses": {
                          "description": "LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn. A campaign can report `status: ACTIVE` and still serve nothing; this array says so.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "status": {
                          "description": "Delivery status. Derived from the platform `effective_status`, so it inherits ancestor pauses (an ACTIVE ad under a PAUSED campaign reads `paused`).",
                          "enum": [
                            "active",
                            "paused",
                            "pending_review",
                            "rejected",
                            "completed",
                            "cancelled",
                            "error"
                          ],
                          "type": "string"
                        },
                        "synced": {
                          "description": "Only on GET /apis/v1/ads/{adId}. An unsynced ad has no `id`.",
                          "type": "boolean"
                        },
                        "targeting": {
                          "description": "The ad set's targeting (age, gender, geo, interests, placements, audience inclusions/exclusions). May be absent if the ad set exposes no targeting or the lookup fails.",
                          "type": "object"
                        },
                        "updatedAt": {
                          "format": "date-time",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "instagramVideoFallback": {
                      "description": "Meta only. `instagram_video_reuploaded`: the video was copied into the ad account, and the ad still references the original post.",
                      "properties": {
                        "kind": {
                          "enum": [
                            "instagram_video_reuploaded",
                            "instagram_video_rehosted_copy"
                          ],
                          "type": "string"
                        },
                        "linkedToOriginalPost": {
                          "description": "True when the ad still references the original Instagram post and keeps its engagement.",
                          "type": "boolean"
                        },
                        "platformError": {
                          "description": "Meta's original refusal.",
                          "properties": {
                            "code": {
                              "type": "integer"
                            },
                            "fbtraceId": {
                              "type": "string"
                            },
                            "message": {
                              "type": "string"
                            },
                            "subcode": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "message"
                          ],
                          "type": "object"
                        },
                        "videoId": {
                          "description": "instagram_video_reuploaded: the copy in the ad account video library (possibly one made by an earlier boost of the same media, reused).",
                          "type": "string"
                        }
                      },
                      "required": [
                        "kind",
                        "linkedToOriginalPost",
                        "platformError",
                        "videoId"
                      ],
                      "type": "object"
                    },
                    "message": {
                      "type": "string"
                    },
                    "warnings": {
                      "description": "Human-readable notes about the boost. With instagramVideoFallback: one line saying how the Instagram video was boosted. `activation_failed:` (Meta): Meta refused the final switch to ACTIVE of the campaign, ad set or ad this boost created.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Boost post as ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.boost_post@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "ae6e3447dae7a9e0ff724af8f7db71a00421ca0b5265c67d4ff0008c4aa1ae48"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_boost",
          "method": "POST",
          "path": "/apis/v1/ads/boost"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_boost"
      }
    },
    "/apis/v1/ads/business-centers": {
      "get": {
        "description": "Ad Accounts. Read only. Returns the TikTok Business Centers (BCs) the connected `tiktokads` account can read. Each BC reports its advertiser count so callers can build agency-style pickers without re-walking `/apis/v1/ads/accounts` per BC. TikTok-only. Solo advertisers (non-agency tokens) return an empty array.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_business_centers",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "businessCenters": {
                      "items": {
                        "description": "TikTok Business Center entity. Returned by `GET /apis/v1/ads/business-centers`. BCs are TikTok's agency container: one BC owns N advertisers (ad accounts).",
                        "properties": {
                          "advertiserCount": {
                            "description": "Number of advertisers reachable under this BC for the calling token.",
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "bcId": {
                            "description": "Business Center ID",
                            "type": "string"
                          },
                          "name": {
                            "description": "Display name set by the BC owner",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Business centers"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List TikTok Business Centers",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ads_business_centers@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "01a66a6cd24206627b811984ef73c70b2fc65481b5695df46142d090e1798fab"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_business_centers",
          "method": "GET",
          "path": "/apis/v1/ads/business-centers"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_business_centers"
      }
    },
    "/apis/v1/ads/businesses": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the Meta business portfolios the connected user belongs to, with their verification status. Business Manager portfolios the connected Meta user belongs to (Meta's `/me/businesses`), rows returned verbatim (id, name, verification_status, created_time). Token-scoped, so no `adAccountId` is needed. For TikTok Business Centers use `GET /apis/v1/ads/business-centers`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_businesses",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Rows per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "description": "Raw Meta business row (id, name, verification_status, created_time).",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Businesses (raw Meta shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Businesses list",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_meta_businesses@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6c2008cfb411f8c66c6146d45cb2ef0135fa644095ebd5722647177a64d6e1b1"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_businesses",
          "method": "GET",
          "path": "/apis/v1/ads/businesses"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_businesses"
      }
    },
    "/apis/v1/ads/businesses/users": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the people and system users of a Meta business portfolio, with the ids you need to assign them to Pages or ad accounts. People and system users of a Meta business portfolio, with the business-scoped ids that `POST /apis/v1/ads/accounts/users` and `POST /apis/v1/ads/page-users` take. The connected Meta user must be an admin of the portfolio.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_businesses_users",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta business portfolio id.",
            "in": "query",
            "name": "businessId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "businessId": {
                      "type": "string"
                    },
                    "systemUsers": {
                      "items": {
                        "properties": {
                          "email": {
                            "type": "string"
                          },
                          "id": {
                            "description": "Business-scoped user id.",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "role": {
                            "description": "Meta role in the portfolio, e.g. ADMIN or EMPLOYEE.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "users": {
                      "items": {
                        "properties": {
                          "email": {
                            "type": "string"
                          },
                          "id": {
                            "description": "Business-scoped user id.",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "role": {
                            "description": "Meta role in the portfolio, e.g. ADMIN or EMPLOYEE.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Business users"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Business users",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_meta_business_users@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "fd65ed1cf0840d405d2c239e62f9b5313b1a653e7b10e3cceef54b7a2c46fc8a"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_businesses_users",
          "method": "GET",
          "path": "/apis/v1/ads/businesses/users"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_businesses_users"
      }
    },
    "/apis/v1/ads/call": {
      "post": {
        "description": "Messaging Ads. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates a click-to-call ad that spends the given budget. Creates a Meta ad with a Call Now button that dials your phone number, optimized for quality calls. Same shape and flow as POST /apis/v1/ads/ctwa, but the CTA is CALL_NOW dialing `phoneNumber` via a tel: link. Supports the same single-creative and multi-creative shapes as CTWA. The ad set is destination_type PHONE_CALL optimizing QUALITY_CALL. The campaign objective defaults to OUTCOME_LEADS.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_call",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "linkUrl": "https://example.com/landing",
                "name": "Winter launch",
                "phoneNumber": "example"
              },
              "schema": {
                "additionalProperties": true,
                "description": "Besides the `required` list, the request must use EXACTLY ONE of these shapes: Single-creative: `headline`, `body`, and one of `imageUrl` / `video`, OR `platformPostId` / `objectStoryId` to reuse an organic post.",
                "properties": {
                  "adAccountId": {
                    "description": "Meta ad account ID, e.g. `act_123456789`.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "adSetId": {
                    "description": "Attaches the creatives to this EXISTING messaging ad set instead of building a campaign, so the ad set keeps its learning phase. Its `destination_type` must match the ad's destination. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "adSetName": {
                    "description": "Exact name for the ad set this request provisions. Omitted keeps ` - Ad Set`. Ignored with `adSetId`.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "adSetStatus": {
                    "description": "Ad-set-level status, same semantics as `POST /apis/v1/ads/create`. Sets the new ad set's switch alone and overrides `status` for it.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "adStatus": {
                    "description": "Request-side publish switch for `adStatus` on ad creation endpoints only (`status`, `campaignStatus` and `adSetStatus` carry their own inline ACTIVE/PAUSED enum there; the status-update endpoints are a separate lowercase `active`/`paused`…",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "advantageAudience": {
                    "description": "Meta's Advantage+ audience expansion. `0` (default) keeps targeting strict; `1` lets Meta expand beyond the supplied targeting when its delivery system finds better matches. Always sent on CREATE (Meta requires it).",
                    "enum": [
                      0,
                      1
                    ],
                    "type": "integer"
                  },
                  "ageMax": {
                    "maximum": 65,
                    "minimum": 13,
                    "type": "integer"
                  },
                  "ageMin": {
                    "maximum": 65,
                    "minimum": 13,
                    "type": "integer"
                  },
                  "audienceExclude": {
                    "description": "Custom or lookalike audience ids to exclude. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "audienceId": {
                    "description": "Custom audience ID to target. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "audienceInclude": {
                    "description": "Custom or lookalike audience ids to include. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "behaviors": {
                    "description": "Behavior ids from /apis/v1/ads/targeting/search?dimension=behavior. Meta: each dimension is its own flexible_spec entry (OR within, AND across). TikTok: video/creator interaction categories, sent as the ad group's actions.",
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "bidAmount": {
                    "description": "Whole currency units (e.g. `5` = $5.00 on a USD account). Required when `bidStrategy` is `LOWEST_COST_WITH_BID_CAP` or `COST_CAP`; rejected otherwise.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "bidStrategy": {
                    "description": "Meta bid strategy applied to the shared ad set. Defaults to `LOWEST_COST_WITHOUT_CAP` (auto-bid) when omitted. `LOWEST_COST_WITH_BID_CAP` and `COST_CAP` require `bidAmount`. `LOWEST_COST_WITH_MIN_ROAS` requires `roasAverageFloor`.",
                    "enum": [
                      "LOWEST_COST_WITHOUT_CAP",
                      "LOWEST_COST_WITH_BID_CAP",
                      "COST_CAP",
                      "LOWEST_COST_WITH_MIN_ROAS"
                    ],
                    "type": "string"
                  },
                  "body": {
                    "description": "Primary text shown above the image / video. Single-creative shape only. Mutually exclusive with `creatives[]`.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "budgetAmount": {
                    "description": "Budget amount in the ad account's currency major units (e.g. dollars for USD, not cents). Must be > 0. Required unless `adSetId` is set (the ad set owns it) or `existingCampaignId` names a campaign with a campaign budget.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "budgetLevel": {
                    "description": "Where the budget lives. `adset` (default) puts it on the new ad set. `campaign` creates an Advantage campaign budget (CBO): the budget and bid strategy sit on the campaign and the ad set inherits them, same as POST /apis/v1/ads/create.",
                    "enum": [
                      "adset",
                      "campaign"
                    ],
                    "type": "string"
                  },
                  "budgetType": {
                    "description": "Required unless `adSetId` is set or `existingCampaignId` names a campaign with a campaign budget. `lifetime` requires `endDate`.",
                    "enum": [
                      "daily",
                      "lifetime"
                    ],
                    "type": "string"
                  },
                  "campaignName": {
                    "description": "Exact name for the campaign this request provisions. Omitted keeps ` - Campaign`. Ignored with `adSetId` (the ad set already has a campaign).",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "campaignStatus": {
                    "description": "Campaign-level status, same semantics as `POST /apis/v1/ads/create`. Defaults to `status`. `PAUSED`: holds the new campaign off while the ad set and ads switch on (one resume call brings the whole hierarchy live).",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "carouselCards": {
                    "description": "Messaging and CTWA only (a 400 on POST /apis/v1/ads/call). A hand-built carousel of 2-10 image cards, sent to Meta in the given order as `link_data.child_attachments`.",
                    "items": {
                      "description": "One card of a messaging ad carousel (Meta link_data.child_attachments). Every card opens the same conversation, so a card has no link of its own.",
                      "properties": {
                        "callToAction": {
                          "description": "Optional. Must equal the destination's messaging call to action (WHATSAPP_MESSAGE for whatsapp, MESSAGE_PAGE for messenger, INSTAGRAM_MESSAGE for instagram_direct; with `destinations` the first one listed).",
                          "type": "string"
                        },
                        "description": {
                          "description": "Card description, under the title.",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "headline": {
                          "description": "Card title (Meta name).",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Card image. Uploaded to the ad account and sent as the card image_hash (by URL on validateOnly).",
                          "format": "uri",
                          "type": "string"
                        },
                        "linkUrl": {
                          "description": "Not accepted: a 400. The card tap opens the conversation, not a website.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "imageUrl"
                      ],
                      "type": "object"
                    },
                    "maxItems": 10,
                    "minItems": 2,
                    "type": "array"
                  },
                  "cities": {
                    "description": "City-level geo targeting for local CTWA campaigns. Each entry maps to Meta's TargetingGeoLocationCity; `key` is Meta's city ID. `radius` and `distance_unit` are coupled: set both or neither.",
                    "items": {
                      "properties": {
                        "distance_unit": {
                          "enum": [
                            "mile",
                            "kilometer"
                          ],
                          "type": "string"
                        },
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "radius": {
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "countries": {
                    "description": "ISO 3166-1 alpha-2 country codes. Defaults to `[\"US\"]` only when no other geo (`cities`, `regions`, `zips`, `metros`, `customLocations`) is supplied.",
                    "items": {
                      "maxLength": 2,
                      "minLength": 2,
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "countryGroups": {
                    "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                    "items": {
                      "enum": [
                        "africa",
                        "asia",
                        "europe",
                        "north_america",
                        "south_america",
                        "oceania",
                        "central_america",
                        "caribbean",
                        "eea",
                        "euro_area",
                        "nafta",
                        "mercosur",
                        "afta",
                        "apec",
                        "gcc",
                        "cisfta",
                        "emerging_markets",
                        "itunes_app_store",
                        "android_free_store",
                        "android_paid_store"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "creativeFeatures": {
                    "additionalProperties": {
                      "enum": [
                        "OPT_IN",
                        "OPT_OUT"
                      ],
                      "type": "string"
                    },
                    "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                    "type": "object"
                  },
                  "creatives": {
                    "description": "Multi-creative shape: N CTWA ads under one campaign + one ad set, sharing budget and targeting. Fresh and existing creatives can be mixed. Each entry supplies headline, body, and image/video, or a platformPostId or objectStoryId reference.",
                    "items": {
                      "description": "Supply headline, body, and image/video; or body and carouselCards (no headline); or exactly one existing post reference. References cannot be combined with headline, body, imageUrl, video or carouselCards; welcomeMessage works on all three.",
                      "properties": {
                        "body": {
                          "description": "Primary text shown above the image / video.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "carouselCards": {
                          "description": "A 2-10 card carousel for this entry instead of `imageUrl` / `video`; `body` is required. Same rules as the top-level `carouselCards`. Carousel and single-media entries can be mixed on one ad set.",
                          "items": {
                            "description": "One card of a messaging ad carousel (Meta link_data.child_attachments). Every card opens the same conversation, so a card has no link of its own.",
                            "properties": {
                              "callToAction": {
                                "description": "Optional. Must equal the destination's messaging call to action (WHATSAPP_MESSAGE for whatsapp, MESSAGE_PAGE for messenger, INSTAGRAM_MESSAGE for instagram_direct; with `destinations` the first one listed).",
                                "type": "string"
                              },
                              "description": {
                                "description": "Card description, under the title.",
                                "maxLength": 255,
                                "type": "string"
                              },
                              "headline": {
                                "description": "Card title (Meta name).",
                                "maxLength": 255,
                                "type": "string"
                              },
                              "imageUrl": {
                                "description": "Card image. Uploaded to the ad account and sent as the card image_hash (by URL on validateOnly).",
                                "format": "uri",
                                "type": "string"
                              },
                              "linkUrl": {
                                "description": "Not accepted: a 400. The card tap opens the conversation, not a website.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "imageUrl"
                            ],
                            "type": "object"
                          },
                          "maxItems": 10,
                          "minItems": 2,
                          "type": "array"
                        },
                        "creativeFeatures": {
                          "additionalProperties": {
                            "enum": [
                              "OPT_IN",
                              "OPT_OUT"
                            ],
                            "type": "string"
                          },
                          "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                          "type": "object"
                        },
                        "existingPostId": {
                          "description": "Alias of platformPostId, kept for existing callers. Sending both with different values is a 400.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "headline": {
                          "maxLength": 255,
                          "minLength": 1,
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Image asset. Mutually exclusive with this entry's `video`. Required if neither `video` nor an existing post reference is supplied.",
                          "format": "uri",
                          "type": "string"
                        },
                        "objectStoryId": {
                          "description": "Messaging and CTWA only. Raw Facebook pageId_postId reference, used as object_story_id even with an Instagram account. Mutually exclusive with platformPostId and fresh creative fields.",
                          "pattern": "^\\d+_\\d+$",
                          "type": "string"
                        },
                        "platformPostId": {
                          "description": "Messaging and CTWA only. Platform post or reel ID, the same input boostPost takes as platformPostId. Mutually exclusive with objectStoryId and fresh creative fields. Facebook IDs become object_story_id.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "video": {
                          "description": "Video creative. Mutually exclusive with this entry's `imageUrl`. Required if neither `imageUrl` nor an existing post reference is supplied.",
                          "properties": {
                            "id": {
                              "description": "Reuse a video already uploaded to this ad account (list them with GET /apis/v1/ads/videos) instead of re-uploading. Wins over `url`. Provide either `url` or `id`.",
                              "type": "string"
                            },
                            "thumbnailUrl": {
                              "description": "OPTIONAL: when omitted, the poster is auto-generated from Meta's own preferred video thumbnail. When Meta produces no candidate the request fails with a 502 platform_error (reason: video_thumbnail_unavailable).",
                              "format": "uri",
                              "type": "string"
                            },
                            "url": {
                              "description": "Public URL of the video to upload. Provide either `url` or `id`.",
                              "format": "uri",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "welcomeMessage": {
                          "description": "Custom chat welcome message for this entry: `text` plus exactly one of `prefillText` or `quickReplies` (400 otherwise). Same shape as the top-level `welcomeMessage` of the single-creative shape.",
                          "properties": {
                            "prefillText": {
                              "description": "Message put into the user's text input, ready to send. Replaces Meta's default. Exactly one of prefillText or quickReplies.",
                              "minLength": 1,
                              "type": "string"
                            },
                            "quickReplies": {
                              "description": "Tappable chips under the greeting instead of a prefilled message. Exactly one of prefillText or quickReplies.",
                              "items": {
                                "properties": {
                                  "payload": {
                                    "maxLength": 1000,
                                    "minLength": 1,
                                    "type": "string"
                                  },
                                  "title": {
                                    "description": "Chip label the person taps.",
                                    "maxLength": 20,
                                    "minLength": 1,
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "payload",
                                  "title"
                                ],
                                "type": "object"
                              },
                              "maxItems": 13,
                              "minItems": 1,
                              "type": "array"
                            },
                            "text": {
                              "description": "Greeting shown when the chat opens. Replaces Meta's default.",
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "currency": {
                    "description": "ISO 4217 currency code matching the ad account's currency (e.g. `USD`).",
                    "maxLength": 3,
                    "minLength": 3,
                    "type": "string"
                  },
                  "customLocations": {
                    "description": "Point-radius geo (Meta `geo_locations.custom_locations`). Use for targeting a radius around a specific lat/long when no Meta city/region key fits. `distanceUnit` is required.",
                    "items": {
                      "properties": {
                        "address": {
                          "type": "string"
                        },
                        "distanceUnit": {
                          "enum": [
                            "mile",
                            "kilometer"
                          ],
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        },
                        "name": {
                          "type": "string"
                        },
                        "radius": {
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "distanceUnit",
                        "latitude",
                        "longitude",
                        "radius"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "description": {
                    "description": "Link description, independent of `headline` and `body`: Meta's `link_data.description`, `video_data.link_description` on video, and the shared description of a `placementAssets` feed.",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "dsaBeneficiary": {
                    "description": "Legal entity that benefits from the ad. Required when targeting EU users (EU DSA, Article 26).",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "dsaPayor": {
                    "description": "Legal entity that pays for the ad. Can differ from `dsaBeneficiary` (for example, an agency paying for a client's ads). Same rules as `dsaBeneficiary`: required for EU targeting unless the ad account has a default payor.",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "endDate": {
                    "description": "ISO 8601 date or date-time, read like `startDate`; a date-only value ends at 23:59:59 local. Required when `budgetType` is `lifetime`.",
                    "type": "string"
                  },
                  "excludedLocations": {
                    "additionalProperties": true,
                    "description": "Geo to exclude, same shape as POST /apis/v1/ads/create (countries, countryGroups, regions, cities, zips, places, neighborhoods, customLocations).",
                    "type": "object"
                  },
                  "existingCampaignId": {
                    "description": "Creates the new messaging ad set (and its ads) under this EXISTING Meta campaign instead of a new one, e.g. several audience ad sets under one campaign. To add ads to an existing ad set instead, use `adSetId`. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "existingPostId": {
                    "description": "Alias of platformPostId, kept for existing callers. Sending both with different values is a 400.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "gender": {
                    "description": "Restrict the audience by gender (Meta `genders`). Omit or send all for everyone; all is ignored in adSetId attach mode. Stored on the ad and read back in `targeting.gender`.",
                    "enum": [
                      "all",
                      "male",
                      "female"
                    ],
                    "type": "string"
                  },
                  "headline": {
                    "description": "Single-creative shape only. Mutually exclusive with `creatives[]`. Required on a single image or video ad (including one built with `placementAssets`); not used by a `carouselCards` ad and not accepted with an existing post reference.",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "imageUrl": {
                    "description": "Image asset for single-creative shape. Mutually exclusive with `video` and with `creatives[]`. Required on the single-creative shape if neither `video` nor an existing post reference is supplied.",
                    "format": "uri",
                    "type": "string"
                  },
                  "incomeTier": {
                    "description": "Normalized household-income tier, same as POST /apis/v1/ads/create. Incompatible with housing, employment and credit specialAdCategories.",
                    "enum": [
                      "top_5",
                      "top_10",
                      "top_10_25",
                      "top_25_50"
                    ],
                    "type": "string"
                  },
                  "interests": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "languages": {
                    "description": "Audience languages (Meta `locales`). A bare ISO 639-1 code targets all regional variants (\"en\" = all English), a region-qualified code a specific one (\"en_GB\", \"pt_BR\"); unknown codes are rejected.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "linkUrl": {
                    "description": "Website shown as the creative's link. Required: Meta rejects tel: as link_data.link; the phone number rides only the CTA.",
                    "format": "uri",
                    "type": "string"
                  },
                  "metros": {
                    "description": "DMA / metro-area geo targeting. `key` is Meta's metro id (e.g. `DMA:807`).",
                    "items": {
                      "properties": {
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "name": {
                    "description": "Ad display name. Used to derive campaign / ad set names. On the multi-creative shape, each ad's Meta name gets a \" #N\" suffix (1-indexed) so Ads Manager shows them as a numbered batch.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "neighborhoods": {
                    "description": "Meta neighborhood keys (from GET /apis/v1/ads/targeting/search).",
                    "items": {
                      "properties": {
                        "key": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "objectStoryId": {
                    "description": "Messaging and CTWA only. Raw Facebook pageId_postId reference, used as object_story_id even with an Instagram account. Mutually exclusive with platformPostId and fresh creative fields.",
                    "pattern": "^\\d+_\\d+$",
                    "type": "string"
                  },
                  "objective": {
                    "description": "Defaults to `OUTCOME_ENGAGEMENT`. `OUTCOME_SALES` and `OUTCOME_LEADS` require additional account configuration (Dataset linked to the WABA for sales) and may be rejected by Meta if missing.",
                    "enum": [
                      "OUTCOME_ENGAGEMENT",
                      "OUTCOME_SALES",
                      "OUTCOME_LEADS"
                    ],
                    "type": "string"
                  },
                  "optimizeCardOrder": {
                    "description": "Only with `carouselCards` (a 400 without them). Single-creative shape; for `creatives[]` set it per entry. Sets the creative's `link_data.multi_share_optimized`. `false`: keeps the cards in the order given.",
                    "type": "boolean"
                  },
                  "pageId": {
                    "description": "Facebook Page the ad runs as, when the connection was granted several Pages. Defaults to the Page bound to the connection. Any Page granted to the connection is accepted; other ids answer 400 listing the granted Pages.",
                    "type": "string"
                  },
                  "phoneNumber": {
                    "description": "E.164 number the CALL_NOW CTA dials (e.g. +34600111222).",
                    "type": "string"
                  },
                  "placements": {
                    "description": "Manual ad placements on the shared ad set. Omit for automatic placements.",
                    "properties": {
                      "audienceNetworkPositions": {
                        "items": {
                          "enum": [
                            "classic",
                            "rewarded_video"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "devicePlatforms": {
                        "description": "Restrict by device. Omit to deliver on both mobile and desktop.",
                        "items": {
                          "enum": [
                            "mobile",
                            "desktop"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "facebookPositions": {
                        "items": {
                          "enum": [
                            "feed",
                            "right_hand_column",
                            "marketplace",
                            "story",
                            "search",
                            "instream_video",
                            "facebook_reels",
                            "facebook_reels_overlay",
                            "profile_feed",
                            "notification"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "instagramPositions": {
                        "items": {
                          "enum": [
                            "stream",
                            "story",
                            "explore",
                            "explore_home",
                            "reels",
                            "profile_feed",
                            "ig_search",
                            "profile_reels"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "messengerPositions": {
                        "items": {
                          "enum": [
                            "messenger_home",
                            "sponsored_messages",
                            "story"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "publisherPlatforms": {
                        "description": "Top-level platforms to deliver on. A position field below is only honoured when its parent platform is included here.",
                        "items": {
                          "enum": [
                            "facebook",
                            "instagram",
                            "threads",
                            "messenger",
                            "audience_network",
                            "whatsapp",
                            "meta"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "threadsPositions": {
                        "items": {
                          "enum": [
                            "threads_stream"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "whatsappPositions": {
                        "items": {
                          "enum": [
                            "status"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "places": {
                    "description": "Meta place keys (from GET /apis/v1/ads/targeting/search).",
                    "items": {
                      "properties": {
                        "key": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "platformPostId": {
                    "description": "Messaging and CTWA only. Platform post or reel ID, the same input boostPost takes as platformPostId. Mutually exclusive with objectStoryId and fresh creative fields. Facebook IDs become object_story_id.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "rawTargeting": {
                    "additionalProperties": true,
                    "description": "Meta targeting spec sent as the BASE layer of the ad set's `targeting`, exactly as POST /apis/v1/ads/create does.",
                    "type": "object"
                  },
                  "regionalRegulatedCategories": {
                    "description": "Meta only. Regional regulation categories required when the ad set targets certain countries (e.g.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "regionalRegulationIdentities": {
                    "additionalProperties": {
                      "type": [
                        "string",
                        "integer"
                      ]
                    },
                    "description": "Meta only. Verified identity IDs of the beneficiary and payer for each declared regionalRegulatedCategories value. Ignored when adSetId adds the ad to an existing ad set.",
                    "type": "object"
                  },
                  "regions": {
                    "description": "Region / state-level geo targeting. `key` is Meta's region ID (lookupable via GET /apis/v1/ads/targeting/search?type=region).",
                    "items": {
                      "properties": {
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "roasAverageFloor": {
                    "description": "Decimal ROAS multiplier (e.g. `2.0` = 2.0× ROAS floor). Required when `bidStrategy` is `LOWEST_COST_WITH_MIN_ROAS`; rejected otherwise. Meta enforces its own upper bound server-side.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "savedTargetingId": {
                    "description": "ID of a saved_targeting audience (POST /apis/v1/ads/audiences), expanded as the base targeting. Precedence: savedTargetingId, then `targeting`, then the flat fields. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "specialAdCategories": {
                    "description": "Meta special ad categories on the new campaign.",
                    "items": {
                      "enum": [
                        "HOUSING",
                        "EMPLOYMENT",
                        "CREDIT",
                        "ISSUES_ELECTIONS_POLITICS",
                        "FINANCIAL_PRODUCTS_SERVICES",
                        "ONLINE_GAMBLING_AND_GAMING"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "specialAdCategoryCountry": {
                    "description": "Countries the special ad category applies to. Requires specialAdCategories.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "startDate": {
                    "description": "When the ad set starts delivering. ISO 8601 date or date-time.",
                    "type": "string"
                  },
                  "status": {
                    "description": "Defaults to `ACTIVE`. `PAUSED` pauses only the top-most object this call creates: the new campaign (ad set and ads switched on), or, with `adSetId`, the new ads themselves.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "targeting": {
                    "description": "Normalized, platform-agnostic ad-targeting spec. Every field is optional; an empty object targets the platform's default broadest audience.",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "tracking": {
                    "description": "Ad tracking. Meta, plus `urlTags` on ChatGPT (OpenAI) and `pixelId` on Reddit. Meta: attaches pixel measurement to the ad regardless of the optimization goal (the \"Website events\" tracking row in Ads Manager).",
                    "properties": {
                      "pixelId": {
                        "description": "Meta Pixel ID to attach for offsite-conversion measurement, or the Reddit pixel of the new ad group.",
                        "type": "string"
                      },
                      "urlTags": {
                        "description": "Click-URL params. Meta: stored on the creative as `url_tags` and returned by GET /apis/v1/ads/{adId}/tracking-tags.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "value": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key",
                            "value"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "userDevice": {
                    "description": "Meta `user_device`.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "userOs": {
                    "description": "Meta `user_os`, e.g. [\"iOS_ver_14.0_and_above\"].",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "video": {
                    "description": "Video creative for single-creative shape. Mutually exclusive with `imageUrl` and with `creatives[]`. Required on the single-creative shape if neither `imageUrl` nor an existing post reference is supplied.",
                    "properties": {
                      "id": {
                        "description": "Reuse a video already uploaded to this ad account (list them with GET /apis/v1/ads/videos) instead of re-uploading. Wins over `url`. Provide either `url` or `id`.",
                        "type": "string"
                      },
                      "thumbnailUrl": {
                        "description": "OPTIONAL: when omitted, the poster is auto-generated from Meta's own preferred video thumbnail. When Meta produces no candidate the request fails with a 502 platform_error (reason: video_thumbnail_unavailable).",
                        "format": "uri",
                        "type": "string"
                      },
                      "url": {
                        "description": "Public URL of the video to upload. Provide either `url` or `id`.",
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "welcomeMessage": {
                    "description": "Custom chat welcome message (Meta's `page_welcome_message`, \"Mensaje de bienvenida\" / \"Mensaje predefinido\" in Ads Manager). Single-creative shape only; for `creatives[]` set it per entry.",
                    "properties": {
                      "prefillText": {
                        "description": "Message put into the user's text input, ready to send. Replaces Meta's default (\"Hi! I want more info.\"). Lets one ad steer the opening message toward what it promotes (e.g. a specific product). Exactly one of prefillText or quickReplies.",
                        "minLength": 1,
                        "type": "string"
                      },
                      "quickReplies": {
                        "description": "Tappable chips under the greeting instead of a prefilled message. Exactly one of prefillText or quickReplies. Put your own campaign or ad key in each payload.",
                        "items": {
                          "properties": {
                            "payload": {
                              "maxLength": 1000,
                              "minLength": 1,
                              "type": "string"
                            },
                            "title": {
                              "description": "Chip label the person taps.",
                              "maxLength": 20,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "payload",
                            "title"
                          ],
                          "type": "object"
                        },
                        "maxItems": 13,
                        "minItems": 1,
                        "type": "array"
                      },
                      "text": {
                        "description": "Greeting shown when the chat opens. Replaces Meta's default (\"Hi! Can we help you?\").",
                        "minLength": 1,
                        "type": "string"
                      }
                    },
                    "required": [
                      "text"
                    ],
                    "type": "object"
                  },
                  "whatsappPhoneNumber": {
                    "description": "WhatsApp only. Optional E.164 number already paired with the Facebook Page. Omit to let Meta select the paired number. Sent to the creative CTA and, when creating a new ad set, its promoted_object.",
                    "pattern": "^\\+[1-9]\\d{6,14}$",
                    "type": "string"
                  },
                  "workEmployers": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "workIndustries": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "workPositions": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "zips": {
                    "description": "ZIP / postal-code geo targeting. `key` is the platform's postal id resolved via /apis/v1/ads/targeting/search.",
                    "items": {
                      "properties": {
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  }
                },
                "required": [
                  "adAccountId",
                  "linkUrl",
                  "name",
                  "phoneNumber"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Response returned by `POST /apis/v1/ads/ctwa` when the request used the single-creative shape (top-level headline / body / imageUrl|video). `adType` is the union discriminator.",
                      "properties": {
                        "ad": {
                          "description": "The persisted Ad document.",
                          "type": "object"
                        },
                        "adType": {
                          "enum": [
                            "single"
                          ],
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "warnings": {
                          "description": "Present when Meta created the ad set differently from the request:",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "ad",
                        "adType",
                        "message"
                      ],
                      "type": "object"
                    },
                    {
                      "description": "Response returned by `POST /apis/v1/ads/ctwa` when the request used the multi-creative shape (`creatives[]`). N persisted Ad documents share the returned `platformCampaignId` and `platformAdSetId`. `adType` is the union discriminator.",
                      "properties": {
                        "adType": {
                          "enum": [
                            "multi"
                          ],
                          "type": "string"
                        },
                        "ads": {
                          "description": "The persisted Ad documents (one per creative), all sharing the same `platformCampaignId` and `platformAdSetId`.",
                          "items": {
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "message": {
                          "type": "string"
                        },
                        "platformAdSetId": {
                          "type": "string"
                        },
                        "platformCampaignId": {
                          "type": "string"
                        },
                        "warnings": {
                          "description": "Present when Meta created the ad set differently from the request:",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "adType",
                        "ads",
                        "message",
                        "platformAdSetId",
                        "platformCampaignId"
                      ],
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Ad(s) created and submitted for review."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create Click-to-Call ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_call_ad@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "309393cf80d3cd3cf95bbf136e1440d20f1e28037dd88f20110e54cac8bcfa4b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_call",
          "method": "POST",
          "path": "/apis/v1/ads/call"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_call"
      }
    },
    "/apis/v1/ads/campaigns": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists your campaigns with spend, impressions and clicks summed across their ads, plus each campaign's status and budget. Campaigns are virtual aggregations over ad documents grouped by platform campaign ID. Metrics (spend, impressions, clicks, etc.) are summed across all ads in each campaign.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta only. Set true to also list campaigns with ZERO ads, with `adCount: 0` and zeroed metrics. Campaign reads aggregate over ad documents, so such campaigns are normally invisible.",
            "in": "query",
            "name": "includeEmpty",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Page number (1-based)",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Matches the web UI's default view. Status is NOT filtered by default; use the `status` param for that.",
            "in": "query",
            "name": "source",
            "required": false,
            "schema": {
              "default": "all",
              "enum": [
                "aisa",
                "all"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "microsoft",
                "meta",
                "x"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter by derived campaign status (post-aggregation)",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "active",
                "paused",
                "pending_review",
                "rejected",
                "completed",
                "cancelled",
                "error"
              ],
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (e.g. act_123 for Meta)",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Platform campaign ID (the `platformCampaignId` on each returned campaign). Returns only that campaign, or an empty list when it is not visible to the caller. Mirrors the same filter on /apis/v1/ads and /apis/v1/ads/tree. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only: Facebook Page ID. Campaigns have no Page of their own, so this keeps campaigns having at least one ad backed by this Page, with adCount and metrics computed over those ads only.",
            "in": "query",
            "name": "pageId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start of metrics date range (YYYY-MM-DD, inclusive). Defaults to 90 days ago when both date params are omitted.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End of metrics date range (YYYY-MM-DD, inclusive). Defaults to today. Max 730-day range.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Return only campaigns that delivered between `fromDate` and `toDate`: spend above zero, or impressions served at zero spend. Unlike `status`, which reads a campaign's CURRENT state, this filters on what happened inside the window.",
            "in": "query",
            "name": "hasDelivery",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Return only campaigns whose spend between `fromDate` and `toDate` reaches this amount, in each campaign's OWN currency (the `currency` field on the campaign). Implies `hasDelivery`; `minSpend=0` applies no filter.",
            "in": "query",
            "name": "minSpend",
            "required": false,
            "schema": {
              "minimum": 0,
              "type": "number"
            }
          },
          {
            "description": "Read the on/off switches live from the platform instead of returning synced values. See \"Status freshness\" in the operation description.",
            "in": "query",
            "name": "live",
            "required": false,
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "campaigns": {
                      "items": {
                        "properties": {
                          "adCount": {
                            "type": "integer"
                          },
                          "advertisingChannelType": {
                            "description": "Google-only. Raw campaign.advertising_channel_type. See AdTreeCampaign.advertisingChannelType.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "bidAmount": {
                            "description": "Representative bid from the top-spending ad set (whole currency units). Meta: populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. LinkedIn: the campaign unitCost, ungated, where 0 is a real delivery-stopping value.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "bidStrategy": {
                            "anyOf": [
                              {
                                "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                                "enum": [
                                  "LOWEST_COST_WITHOUT_CAP",
                                  "LOWEST_COST_WITH_BID_CAP",
                                  "COST_CAP",
                                  "LOWEST_COST_WITH_MIN_ROAS"
                                ],
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Campaign-level bid strategy. Ad sets inherit this unless they override."
                          },
                          "budget": {
                            "anyOf": [
                              {
                                "description": "Budget amount in the ad account's native currency (see the campaign's `currency` field for the code).",
                                "properties": {
                                  "amount": {
                                    "type": "number"
                                  },
                                  "amountMicros": {
                                    "description": "Google only. Exact decimal micros; DAILY uses amount_micros and CUSTOM_PERIOD uses total_amount_micros.",
                                    "pattern": "^\\d+$",
                                    "type": "string"
                                  },
                                  "deliveryMethod": {
                                    "description": "Google only. campaign_budget.delivery_method, typically STANDARD, or null when unavailable.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "explicitlyShared": {
                                    "description": "Google only. True for a shared budget; null when unavailable. Shared writes require allowSharedBudgetUpdate=true; unknown sharing status cannot be overridden.",
                                    "type": [
                                      "boolean",
                                      "null"
                                    ]
                                  },
                                  "resourceName": {
                                    "description": "Google only. campaign_budget.resource_name, or null when unavailable.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "type": {
                                    "enum": [
                                      "daily",
                                      "lifetime"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "amount",
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Effective budget. Google metadata arrives after the next successful sync."
                          },
                          "budgetLevel": {
                            "description": "Canonical CBO/ABO indicator. See AdTreeCampaign.budgetLevel.",
                            "enum": [
                              "campaign",
                              "adset"
                            ],
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignBudget": {
                            "anyOf": [
                              {
                                "description": "Budget amount in the ad account's native currency (see the campaign's `currency` field for the code).",
                                "properties": {
                                  "amount": {
                                    "type": "number"
                                  },
                                  "amountMicros": {
                                    "description": "Google only. Exact decimal micros; DAILY uses amount_micros and CUSTOM_PERIOD uses total_amount_micros.",
                                    "pattern": "^\\d+$",
                                    "type": "string"
                                  },
                                  "deliveryMethod": {
                                    "description": "Google only. campaign_budget.delivery_method, typically STANDARD, or null when unavailable.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "explicitlyShared": {
                                    "description": "Google only. True for a shared budget; null when unavailable. Shared writes require allowSharedBudgetUpdate=true; unknown sharing status cannot be overridden.",
                                    "type": [
                                      "boolean",
                                      "null"
                                    ]
                                  },
                                  "resourceName": {
                                    "description": "Google only. campaign_budget.resource_name, or null when unavailable.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "type": {
                                    "enum": [
                                      "daily",
                                      "lifetime"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "amount",
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Campaign-level budget. Null for ad-set budgets."
                          },
                          "campaignIssuesInfo": {
                            "description": "Platform-reported campaign issues (Meta `issues_info[]`).",
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": [
                              "array",
                              "null"
                            ]
                          },
                          "campaignName": {
                            "type": "string"
                          },
                          "configReadAt": {
                            "description": "Only on GET /apis/v1/ads/campaigns with `live=true`. When `nativeSettings` was read from the platform. Null whenever native settings were not read now.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "currency": {
                            "description": "ISO 4217 currency code for all budget amounts. Budgets are NOT normalized to USD.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "earliestAd": {
                            "format": "date-time",
                            "type": "string"
                          },
                          "isBudgetScheduleEnabled": {
                            "default": false,
                            "description": "Meta-only. Mirrors Campaign.is_budget_schedule_enabled.",
                            "type": "boolean"
                          },
                          "isSmartPlus": {
                            "description": "TikTok only. true when the campaign is an Upgraded Smart+ campaign. See AdTreeCampaign.isSmartPlus.",
                            "type": "boolean"
                          },
                          "latestAd": {
                            "format": "date-time",
                            "type": "string"
                          },
                          "metrics": {
                            "properties": {
                              "actionValues": {
                                "additionalProperties": true,
                                "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                "type": "object"
                              },
                              "actions": {
                                "additionalProperties": true,
                                "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                "type": "object"
                              },
                              "allConversions": {
                                "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                "type": "number"
                              },
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                "type": "number"
                              },
                              "costPerAction": {
                                "additionalProperties": true,
                                "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                "type": "object"
                              },
                              "costPerConversion": {
                                "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                "type": "number"
                              },
                              "costPerThruplay": {
                                "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                "type": "number"
                              },
                              "cpc": {
                                "description": "Cost per click",
                                "type": "number"
                              },
                              "cpm": {
                                "description": "Cost per 1000 impressions",
                                "type": "number"
                              },
                              "ctr": {
                                "description": "Click-through rate (%)",
                                "type": "number"
                              },
                              "engagement": {
                                "type": "integer"
                              },
                              "engagementBreakdown": {
                                "additionalProperties": true,
                                "description": "The single `engagement` total, split into the interactions behind it.",
                                "type": "object"
                              },
                              "funnel": {
                                "additionalProperties": true,
                                "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                "type": "object"
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "inlineLinkClickCtr": {
                                "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "inlineLinkClicks": {
                                "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                "type": "integer"
                              },
                              "lastSyncedAt": {
                                "description": "Present on individual ads only, not on campaign aggregations",
                                "format": "date-time",
                                "type": "string"
                              },
                              "outboundClicks": {
                                "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                "type": "integer"
                              },
                              "outboundClicksCtr": {
                                "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "purchaseValue": {
                                "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                "type": "number"
                              },
                              "reach": {
                                "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                "type": "integer"
                              },
                              "roas": {
                                "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                "type": "number"
                              },
                              "spend": {
                                "type": "number"
                              },
                              "uniqueClicks": {
                                "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                "type": "integer"
                              },
                              "uniqueCtr": {
                                "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                "type": "number"
                              },
                              "video2SecWatchedActions": {
                                "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                "type": "integer"
                              },
                              "video30SecWatchedActions": {
                                "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                "type": "integer"
                              },
                              "video6SecFocusedViews": {
                                "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                "type": "integer"
                              },
                              "video6SecWatchedActions": {
                                "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                "type": "integer"
                              },
                              "videoAvgTimeWatchedActions": {
                                "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                "type": "number"
                              },
                              "videoP100WatchedActions": {
                                "description": "Views reaching 100% of the video's length.",
                                "type": "integer"
                              },
                              "videoP25WatchedActions": {
                                "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                "type": "integer"
                              },
                              "videoP50WatchedActions": {
                                "description": "Views reaching 50% of the video's length.",
                                "type": "integer"
                              },
                              "videoP75WatchedActions": {
                                "description": "Views reaching 75% of the video's length.",
                                "type": "integer"
                              },
                              "videoP95WatchedActions": {
                                "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                "type": "integer"
                              },
                              "videoPlayActions": {
                                "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                "type": "integer"
                              },
                              "videoThruplayWatchedActions": {
                                "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "nativeSettings": {
                            "additionalProperties": true,
                            "description": "TikTok only, only on GET /apis/v1/ads/campaigns with `live=true` and only on campaigns read live.",
                            "type": "object"
                          },
                          "optimizationGoal": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              }
                            ],
                            "description": "The campaign's optimization goal. Every ad set shares one goal: a single string. Ad sets differ: a JSON array of the distinct goals (never a comma-joined string). Element order is not guaranteed; treat it as an unordered set."
                          },
                          "platform": {
                            "enum": [
                              "facebook",
                              "instagram",
                              "tiktok",
                              "linkedin",
                              "pinterest",
                              "google",
                              "twitter",
                              "openai",
                              "reddit",
                              "microsoft"
                            ],
                            "type": "string"
                          },
                          "platformAdAccountId": {
                            "type": "string"
                          },
                          "platformAdAccountName": {
                            "description": "Human-readable advertiser/account name from the platform. Refreshed on every sync.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformCampaignId": {
                            "type": "string"
                          },
                          "platformCampaignStatus": {
                            "description": "Raw platform-level campaign status (Meta `effective_status`; ChatGPT (OpenAI): the campaign's own switch, active / paused / archived; TikTok: the campaign's own switch `operation_status`, ENABLE / DISABLE; Reddit: the campaign's…",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformObjective": {
                            "description": "Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC)",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "promotedObject": {
                            "description": "Meta promoted object at campaign level (conversion event details)",
                            "properties": {
                              "custom_event_type": {
                                "type": "string"
                              },
                              "page_id": {
                                "type": "string"
                              },
                              "pixel_id": {
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "reviewStatus": {
                            "anyOf": [
                              {
                                "description": "Platform-side review state, independent of the delivery `status` and the `configuredStatus` on/off toggle. `in_review` means the platform is still reviewing. Absent when the platform reports no review signal (e.g.",
                                "enum": [
                                  "in_review",
                                  "approved",
                                  "rejected",
                                  "with_issues"
                                ],
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Platform-side review state of the campaign. See AdTreeCampaign.reviewStatus for the full description."
                          },
                          "roasAverageFloor": {
                            "description": "Representative ROAS floor from the top-spending ad set. Decimal multiplier (2.0 = 2.0x).",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "status": {
                            "description": "Delivery status derived from child ad statuses. Distinct from `reviewStatus`.",
                            "enum": [
                              "active",
                              "paused",
                              "pending_review",
                              "rejected",
                              "completed",
                              "cancelled",
                              "error"
                            ],
                            "type": "string"
                          },
                          "statusReadAt": {
                            "description": "Only on GET /apis/v1/ads/campaigns with `live=true`. When `platformCampaignStatus` was read from the platform; null when this campaign could not be read live.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "pagination": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Paginated campaigns"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List campaigns",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_campaigns@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "93e1ea7f28d93b5836dd7b7d8d0c5e05b9e06ddb8072e58a70892e2905355f0e"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns"
      },
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates a campaign on the ad platform; with a budget and an active status it starts spending. validateOnly=true checks the request without acting and needs no confirmation. Creates an empty campaign, paused, so you can add ad sets and ads to it afterwards. Creates a campaign WITHOUT its first ad set / ad, on the platform of the given `connectionId`. Ad sets join it later via `existingCampaignId` on the create endpoints. Created `PAUSED` (TikTok `DISABLE`) unless `status: ACTIVE` where the platform supports it.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_campaigns",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_757082720485182",
                "buyingType": "AUCTION",
                "connectionId": "adc_7f3k2m9q",
                "goal": "app_promotion",
                "isSkadnetworkAttribution": true,
                "name": "iOS app campaign",
                "promotedObject": {
                  "applicationId": "123456789",
                  "objectStoreUrl": "https://apps.apple.com/us/app/id123456789"
                },
                "status": "PAUSED",
                "validateOnly": true
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account id (Meta act_, Google customer id, LinkedIn account id, ...).",
                    "type": "string"
                  },
                  "bidAmount": {
                    "description": "Whole currency units (USD: 5 = $5.00). Required for LOWEST_COST_WITH_BID_CAP and COST_CAP; ignored otherwise. Meta: validated here but NOT stored, since the campaign object only has bid_strategy.",
                    "type": "number"
                  },
                  "bidStrategy": {
                    "description": "Campaign bid strategy. Meta stores `bid_strategy` alongside the budget, so this REQUIRES `budgetAmount` + `budgetType` on the same request (400 without a campaign budget).",
                    "enum": [
                      "LOWEST_COST_WITHOUT_CAP",
                      "LOWEST_COST_WITH_BID_CAP",
                      "COST_CAP",
                      "LOWEST_COST_WITH_MIN_ROAS"
                    ],
                    "type": "string"
                  },
                  "budgetAmount": {
                    "description": "Campaign-level (CBO) budget in WHOLE currency units (USD: 50 = $50.00), NOT cents. Meta's own Marketing API takes this same number in minor units, so it is an easy and expensive mix-up. Requires budgetType.",
                    "type": "number"
                  },
                  "budgetType": {
                    "enum": [
                      "daily",
                      "lifetime"
                    ],
                    "type": "string"
                  },
                  "buyingType": {
                    "description": "Every platform buys at auction by default, so this only needs sending on Meta, and only to choose RESERVED. `AUCTION` is accepted on every platform and changes nothing.",
                    "enum": [
                      "AUCTION",
                      "RESERVED"
                    ],
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "endDate": {
                    "description": "Reddit only (400 elsewhere). Campaign end (ISO 8601); a value without an offset is read in the ad account time zone. Requires a campaign budget (400 otherwise), and is required for `budgetType: lifetime`.",
                    "format": "date-time",
                    "type": "string"
                  },
                  "goal": {
                    "description": "Mapped to the ODAX objective (same mapping as POST /apis/v1/ads/create).",
                    "enum": [
                      "engagement",
                      "traffic",
                      "awareness",
                      "video_views",
                      "lead_generation",
                      "lead_conversion",
                      "job_applicants",
                      "conversions",
                      "app_promotion",
                      "catalog_sales",
                      "page_likes",
                      "page_visits"
                    ],
                    "type": "string"
                  },
                  "isSkadnetworkAttribution": {
                    "description": "Meta app promotion only. Immutable campaign flag. Set true for iOS 14+ SKAdNetwork campaigns and supply promotedObject.applicationId plus promotedObject.objectStoreUrl. The campaign receives promotedObject only when this flag is true.",
                    "type": "boolean"
                  },
                  "locationTargetingType": {
                    "description": "Google only (400 elsewhere). Written on the new campaign.",
                    "enum": [
                      "presence",
                      "presence_or_interest"
                    ],
                    "type": "string"
                  },
                  "manualCpc": {
                    "additionalProperties": false,
                    "description": "Google Search and Display only. Manual CPC bidding. Enhanced CPC is not offered: Google no longer lets Search and Display campaigns enable it. Exclusive with every other strategy field.",
                    "properties": {
                      "maxCpc": {
                        "description": "Max CPC of the ad groups, in the account's currency units: set on the ad group created with the campaign, and on every ad group of the campaign when an update switches it to Manual CPC. Google gives an ad group without one a 0.01 bid.",
                        "exclusiveMinimum": 0,
                        "type": "number"
                      }
                    },
                    "required": [
                      "maxCpc"
                    ],
                    "type": "object"
                  },
                  "name": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "networkSettings": {
                    "additionalProperties": false,
                    "description": "Google Search campaigns only. Which networks the campaign serves on besides Google Search.",
                    "properties": {
                      "displayNetwork": {
                        "description": "campaign.network_settings.target_content_network (Search with Display expansion)",
                        "type": "boolean"
                      },
                      "searchPartners": {
                        "description": "campaign.network_settings.target_search_network",
                        "type": "boolean"
                      }
                    },
                    "type": "object"
                  },
                  "portfolioBidStrategyId": {
                    "description": "Google only. Attach an existing portfolio bid strategy (numeric id from GET /apis/v1/ads/bid-strategies) to the new campaign instead of a standard one. Exclusive with bidStrategy.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "promotedObject": {
                    "additionalProperties": false,
                    "description": "What the ad optimises against. Behaviour depends on the platform. Platforms other than Meta, TikTok, OpenAI and Reddit ignore `promotedObject` entirely. Meta: forwarded to the ad set's `promoted_object` (snake-cased).",
                    "properties": {
                      "applicationId": {
                        "description": "App ID. Required for `goal: app_promotion`.",
                        "type": "string"
                      },
                      "customConversionId": {
                        "description": "Custom Conversion ID, when optimising against one instead of a standard event. Accepted alone by this API, without `pixelId` or `customEventType`.",
                        "type": "string"
                      },
                      "customEventStr": {
                        "description": "Meta only. Pixel custom-event name to optimise against (Meta's `custom_event_str`), exactly as it appears in Events Manager and your CAPI payloads (case-sensitive, not uppercased).",
                        "type": "string"
                      },
                      "customEventType": {
                        "description": "The event the campaign/ad group optimises against. Meta: a standard event like `PURCHASE`, `LEAD`, `COMPLETE_REGISTRATION`, `ADD_TO_CART`. Uppercased internally, so any case works. Required for `goal: conversions`.",
                        "type": "string"
                      },
                      "objectStoreUrl": {
                        "description": "App Store / Play Store listing URL. Required for `goal: app_promotion`.",
                        "format": "uri",
                        "type": "string"
                      },
                      "offlineConversionDataSetId": {
                        "description": "Meta only. Offline event set (dataset) to optimise toward. Post-merger these are datasets: the id is the dataset id (for pixel-backed datasets, the pixel id).",
                        "type": "string"
                      },
                      "pageId": {
                        "description": "Facebook Page ID. Used by `goal: lead_generation`. Auto-filled from the connected Page when omitted.",
                        "type": "string"
                      },
                      "pixelId": {
                        "description": "Pixel ID. Meta: Facebook Pixel ID, required for `goal: conversions`.",
                        "type": "string"
                      },
                      "productCatalogId": {
                        "description": "Optional catalog ID. A catalog ID cannot replace productSetId.",
                        "type": "string"
                      },
                      "productSetId": {
                        "description": "Meta product SET ID, for example from GET /apis/v1/ads/catalogs/{catalogId}/product-sets. Creating catalog ads needs only ads_management on the Meta login, not catalog_management. Where it goes.",
                        "type": "string"
                      },
                      "whatsappPhoneNumber": {
                        "description": "Meta only. WhatsApp number on messaging-destination ad sets.",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "roasAverageFloor": {
                    "description": "Decimal ROAS multiplier (2.0 = 2.0x). Required for LOWEST_COST_WITH_MIN_ROAS.",
                    "type": "number"
                  },
                  "specialAdCategories": {
                    "items": {
                      "enum": [
                        "HOUSING",
                        "EMPLOYMENT",
                        "CREDIT",
                        "ISSUES_ELECTIONS_POLITICS",
                        "FINANCIAL_PRODUCTS_SERVICES",
                        "ONLINE_GAMBLING_AND_GAMING"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "startDate": {
                    "description": "Reddit only (400 elsewhere). Campaign start (ISO 8601); a value without an offset is read in the ad account time zone. Requires a campaign budget (`budgetAmount` + `budgetType`, 400 otherwise). Defaults to now.",
                    "format": "date-time",
                    "type": "string"
                  },
                  "status": {
                    "default": "PAUSED",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "targetImpressionShare": {
                    "additionalProperties": false,
                    "description": "Google Search only. Target impression share bidding. Exclusive with bidStrategy, portfolioBidStrategyId and manualCpc; bidAmount is refused alongside it (the ceiling is maxCpc).",
                    "properties": {
                      "location": {
                        "enum": [
                          "ANYWHERE_ON_PAGE",
                          "TOP_OF_PAGE",
                          "ABSOLUTE_TOP_OF_PAGE"
                        ],
                        "type": "string"
                      },
                      "maxCpc": {
                        "description": "Max CPC bid limit, in the account's currency units. Google requires it.",
                        "exclusiveMinimum": 0,
                        "type": "number"
                      },
                      "percent": {
                        "description": "Target share of impressions, in percent (65 = 65%). Sent to Google as location_fraction_micros (1% = 10,000).",
                        "exclusiveMinimum": 0,
                        "maximum": 100,
                        "type": "number"
                      }
                    },
                    "required": [
                      "location",
                      "maxCpc",
                      "percent"
                    ],
                    "type": "object"
                  },
                  "validateOnly": {
                    "description": "Meta and ChatGPT (OpenAI). Runs campaign validation without creating or persisting a campaign; Idempotency-Key storage is bypassed. Returns HTTP 200 with validateOnly true and status VALIDATED.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "adAccountId",
                  "goal",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "campaignId": {
                      "const": "",
                      "description": "Empty because no campaign was created.",
                      "type": "string"
                    },
                    "objective": {
                      "type": "string"
                    },
                    "status": {
                      "const": "VALIDATED",
                      "type": "string"
                    },
                    "validateOnly": {
                      "description": "Always true.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign validation passed without creating a campaign."
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "campaignId": {
                      "description": "Platform id of the new campaign",
                      "type": "string"
                    },
                    "objective": {
                      "description": "Resolved ODAX objective (e.g. OUTCOME_SALES).",
                      "type": "string"
                    },
                    "status": {
                      "enum": [
                        "ACTIVE",
                        "PAUSED"
                      ],
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a standalone campaign",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_campaign@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "493e1dca4b3fa4a8bf12f9e5647331092eeb299d10039907fe102054baddad4e"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_campaigns",
          "method": "POST",
          "path": "/apis/v1/ads/campaigns"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_campaigns"
      }
    },
    "/apis/v1/ads/campaigns/bulk-status": {
      "post": {
        "description": "Ad Campaigns. A pause needs ads:write. A change to active turns delivery on: it needs ads:spend and X-Aisa-Confirm: spend. Pauses or resumes up to 50 campaigns in one call, with a separate result per campaign so one failure does not block the rest. Each campaign is updated concurrently, and the response contains a per-campaign result so a single bad row does not fail the whole batch.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_campaigns_bulk_status",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "campaigns": [
                  {
                    "platform": "google",
                    "platformCampaignId": "23456789012"
                  },
                  {
                    "platform": "facebook",
                    "platformCampaignId": "120210000000000000"
                  }
                ],
                "connectionId": "adc_7f3k2m9q",
                "status": "paused"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "campaigns": {
                    "items": {
                      "properties": {
                        "platform": {
                          "description": "The ad platform, e.g. `google` for Google Ads. The ads connection slug (`googleads`, `tiktokads`, ...) is accepted as an alias. `metaads` is not: send `facebook` or `instagram`. Filled from the connection when omitted.",
                          "enum": [
                            "facebook",
                            "instagram",
                            "tiktok",
                            "linkedin",
                            "pinterest",
                            "google",
                            "twitter",
                            "openai",
                            "reddit",
                            "microsoft",
                            "googleads",
                            "tiktokads",
                            "linkedinads",
                            "pinterestads",
                            "xads",
                            "openaiads",
                            "redditads",
                            "microsoftads",
                            "meta",
                            "x"
                          ],
                          "type": "string"
                        },
                        "platformCampaignId": {
                          "description": "The campaign id on the ad platform (e.g.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "platformCampaignId"
                      ],
                      "type": "object"
                    },
                    "maxItems": 50,
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "status": {
                    "enum": [
                      "active",
                      "paused"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "campaigns",
                  "status"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "results": {
                      "items": {
                        "properties": {
                          "error": {
                            "type": "string"
                          },
                          "platform": {
                            "type": "string"
                          },
                          "platformCampaignId": {
                            "type": "string"
                          },
                          "platformCampaignStatus": {
                            "description": "The campaign's own switch read back from the platform; null when it could not be read.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "skipped": {
                            "enum": [
                              0,
                              1
                            ],
                            "type": "integer"
                          },
                          "updated": {
                            "enum": [
                              0,
                              1
                            ],
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "status": {
                      "enum": [
                        "active",
                        "paused"
                      ],
                      "type": "string"
                    },
                    "totals": {
                      "properties": {
                        "failed": {
                          "type": "integer"
                        },
                        "skipped": {
                          "type": "integer"
                        },
                        "updated": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Per-campaign results"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Pause or resume many campaigns",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.bulk_update_ad_campaign_status@1",
          "required_scope": "ads:write",
          "scope_rule": "Pausing needs ads:write; turning delivery on needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "66b927a2daf9187de80c520c89b3c8876cd1deaba6efc78a655590d688d7d982"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_campaigns_bulk_status",
          "method": "POST",
          "path": "/apis/v1/ads/campaigns/bulk-status"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_campaigns_bulk_status"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}": {
      "delete": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Deletes a campaign on its platform, including a campaign that never got any ads. Only the campaign itself is sent to the platform: Meta, Google, TikTok, LinkedIn and X delete it. OpenAI, Reddit and Pinterest have no campaign delete and archive it instead (see below). Locally, all Ad documents for this campaign are marked `status: cancelled`. ### Empty campaigns\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_campaigns_campaignid",
        "parameters": [
          {
            "description": "Platform campaign ID",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "connectionId": "adc_7f3k2m9q"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "X only, for an EMPTY campaign that was never synced: the X ad account id the campaign belongs to (lowercase letters and digits). The synced campaign's ad account wins when there is one. Also accepted on the query string.",
                    "pattern": "^[0-9a-z]{1,32}$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "platform": {
                    "description": "Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "microsoft",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adCount": {
                      "description": "Number of local Ad docs marked cancelled",
                      "type": "integer"
                    },
                    "deleted": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete a campaign",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_campaign@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6b4854d957183a32d687da85151ebc5406fea653b78cabcb9f7de783f22ac343"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_campaigns_campaignid",
          "method": "DELETE",
          "path": "/apis/v1/ads/campaigns/{campaignId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_campaigns_campaignid"
      },
      "get": {
        "description": "Ad Campaigns. Read only. Shows a Meta campaign's current settings straight from Meta, such as its objective, budget, bid strategy, schedule and delivery issues. It reads one campaign live from Meta, returned verbatim, so a caller that knows a campaign id no longer has to page `GET /apis/v1/ads/campaigns` to find it.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid",
        "parameters": [
          {
            "description": "Meta campaign id (platformCampaignId).",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Graph field override. Supports nested {} projections and Graph field modifiers.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "campaign": {
                      "description": "Raw Meta campaign; keys are the requested Graph fields.",
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The campaign as returned by Meta"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get live campaign details",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_campaign_details@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "bf7ef2bf55b1757f082a6da2fe9c03b6fe29dec25ecc197ecaf799f8cdbb0780"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid"
      },
      "put": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Changes a campaign's budget or bidding. Changes a campaign's settings, such as its name, budget, bidding or tracking URLs. Send at least one of `budget`, `bidStrategy`, `portfolioBidStrategyId`, `targetImpressionShare`, `manualCpc`, `networkSettings`, `trackingUrlTemplate`, `finalUrlSuffix`, `sharedBudgetId`, `name` or `platformSpecificData`. An unsupported field is always an error, never a silent drop.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_campaigns_campaignid",
        "parameters": [
          {
            "description": "Platform campaign ID",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "budget": {
                  "amount": 8,
                  "type": "daily"
                },
                "connectionId": "adc_7f3k2m9q",
                "platform": "facebook"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "allowSharedBudgetUpdate": {
                    "default": false,
                    "description": "Google only. Explicitly allow changing a shared campaign budget (flagged as shared by Google, or used by more than one campaign), affecting every campaign that uses it. Does not bypass an unknown sharing state.",
                    "type": "boolean"
                  },
                  "bidAmount": {
                    "description": "Google only. Whole currency units (USD: 12 = $12.00). Max CPC for LOWEST_COST_WITH_BID_CAP, CPA target for COST_CAP; required for both.",
                    "type": "number"
                  },
                  "bidStrategy": {
                    "description": "Meta + Google. Meta: the campaign default that ad sets inherit unless they override it. Google: the campaign's own bidding strategy.",
                    "enum": [
                      "LOWEST_COST_WITHOUT_CAP",
                      "LOWEST_COST_WITH_BID_CAP",
                      "COST_CAP",
                      "LOWEST_COST_WITH_MIN_ROAS"
                    ],
                    "type": "string"
                  },
                  "budget": {
                    "description": "Meta CBO, Google daily, or OpenAI Ads or Reddit Ads daily or lifetime campaign budget, in whole currency units.",
                    "properties": {
                      "amount": {
                        "description": "Budget amount in the ad account's currency",
                        "type": "number"
                      },
                      "type": {
                        "enum": [
                          "daily",
                          "lifetime"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "amount",
                      "type"
                    ],
                    "type": "object"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "finalUrlSuffix": {
                    "description": "Google only. campaign.final_url_suffix; an empty string clears it.",
                    "type": "string"
                  },
                  "manualCpc": {
                    "additionalProperties": false,
                    "description": "Google Search and Display only. Manual CPC bidding. Enhanced CPC is not offered: Google no longer lets Search and Display campaigns enable it. Exclusive with every other strategy field.",
                    "properties": {
                      "maxCpc": {
                        "description": "Max CPC of the ad groups, in the account's currency units: set on the ad group created with the campaign, and on every ad group of the campaign when an update switches it to Manual CPC. Google gives an ad group without one a 0.01 bid.",
                        "exclusiveMinimum": 0,
                        "type": "number"
                      }
                    },
                    "required": [
                      "maxCpc"
                    ],
                    "type": "object"
                  },
                  "name": {
                    "description": "Meta and Reddit. Rename the campaign.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "networkSettings": {
                    "additionalProperties": false,
                    "description": "Google Search campaigns only. Which networks the campaign serves on besides Google Search.",
                    "properties": {
                      "displayNetwork": {
                        "description": "campaign.network_settings.target_content_network (Search with Display expansion)",
                        "type": "boolean"
                      },
                      "searchPartners": {
                        "description": "campaign.network_settings.target_search_network",
                        "type": "boolean"
                      }
                    },
                    "type": "object"
                  },
                  "platform": {
                    "description": "Required: platform campaign IDs are not globally unique. Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "microsoft",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  },
                  "platformSpecificData": {
                    "description": "Meta only. Platform implied by the `platform` body param, same convention as POST /apis/v1/ads/create.",
                    "properties": {
                      "spendCap": {
                        "description": "Campaign lifetime spend cap, in the ad account's currency (Meta `spend_cap`). Pass null to remove the cap; 0 is rejected by Meta.",
                        "type": [
                          "number",
                          "null"
                        ]
                      }
                    },
                    "type": "object"
                  },
                  "portfolioBidStrategyId": {
                    "description": "Google only. Attach an existing portfolio bid strategy (numeric id from GET /apis/v1/ads/bid-strategies) instead of setting bidStrategy. Exclusive with bidStrategy.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "roasAverageFloor": {
                    "description": "Google only. Decimal ROAS multiplier (2.0 = 2.0x), required for LOWEST_COST_WITH_MIN_ROAS.",
                    "type": "number"
                  },
                  "sharedBudgetId": {
                    "description": "Google only. Move the campaign onto this shared budget (id from GET /apis/v1/ads/shared-budgets), or null to move it back onto a budget of its own sized by `budget`.",
                    "pattern": "^\\d+$",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "targetImpressionShare": {
                    "additionalProperties": false,
                    "description": "Google Search only. Target impression share bidding. Exclusive with bidStrategy, portfolioBidStrategyId and manualCpc; bidAmount is refused alongside it (the ceiling is maxCpc).",
                    "properties": {
                      "location": {
                        "enum": [
                          "ANYWHERE_ON_PAGE",
                          "TOP_OF_PAGE",
                          "ABSOLUTE_TOP_OF_PAGE"
                        ],
                        "type": "string"
                      },
                      "maxCpc": {
                        "description": "Max CPC bid limit, in the account's currency units. Google requires it.",
                        "exclusiveMinimum": 0,
                        "type": "number"
                      },
                      "percent": {
                        "description": "Target share of impressions, in percent (65 = 65%). Sent to Google as location_fraction_micros (1% = 10,000).",
                        "exclusiveMinimum": 0,
                        "maximum": 100,
                        "type": "number"
                      }
                    },
                    "required": [
                      "location",
                      "maxCpc",
                      "percent"
                    ],
                    "type": "object"
                  },
                  "trackingUrlTemplate": {
                    "description": "Google only. campaign.tracking_url_template; an empty string clears it.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "description": "Echoes back only the fields you sent, plus `updated`.",
                  "properties": {
                    "bidAmount": {
                      "type": "number"
                    },
                    "bidStrategy": {
                      "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                      "enum": [
                        "LOWEST_COST_WITHOUT_CAP",
                        "LOWEST_COST_WITH_BID_CAP",
                        "COST_CAP",
                        "LOWEST_COST_WITH_MIN_ROAS"
                      ],
                      "type": "string"
                    },
                    "budget": {
                      "description": "Budget amount in the ad account's native currency (see the campaign's `currency` field for the code).",
                      "properties": {
                        "amount": {
                          "type": "number"
                        },
                        "amountMicros": {
                          "description": "Google only. Exact decimal micros; DAILY uses amount_micros and CUSTOM_PERIOD uses total_amount_micros.",
                          "pattern": "^\\d+$",
                          "type": "string"
                        },
                        "deliveryMethod": {
                          "description": "Google only. campaign_budget.delivery_method, typically STANDARD, or null when unavailable.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "explicitlyShared": {
                          "description": "Google only. True for a shared budget; null when unavailable. Shared writes require allowSharedBudgetUpdate=true; unknown sharing status cannot be overridden.",
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "resourceName": {
                          "description": "Google only. campaign_budget.resource_name, or null when unavailable.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "type": {
                          "enum": [
                            "daily",
                            "lifetime"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "amount",
                        "type"
                      ],
                      "type": "object"
                    },
                    "budgetLevel": {
                      "enum": [
                        "campaign"
                      ],
                      "type": "string"
                    },
                    "finalUrlSuffix": {
                      "type": "string"
                    },
                    "manualCpc": {
                      "description": "Google Search and Display only. Manual CPC bidding. Enhanced CPC is not offered: Google no longer lets Search and Display campaigns enable it. Exclusive with every other strategy field.",
                      "properties": {
                        "maxCpc": {
                          "description": "Max CPC of the ad groups, in the account's currency units: set on the ad group created with the campaign, and on every ad group of the campaign when an update switches it to Manual CPC. Google gives an ad group without one a 0.01 bid.",
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "maxCpc"
                      ],
                      "type": "object"
                    },
                    "networkSettings": {
                      "description": "Google Search campaigns only. Which networks the campaign serves on besides Google Search.",
                      "properties": {
                        "displayNetwork": {
                          "description": "campaign.network_settings.target_content_network (Search with Display expansion)",
                          "type": "boolean"
                        },
                        "searchPartners": {
                          "description": "campaign.network_settings.target_search_network",
                          "type": "boolean"
                        }
                      },
                      "type": "object"
                    },
                    "platformSpecificData": {
                      "type": "object"
                    },
                    "portfolioBidStrategyId": {
                      "description": "Google only. Echoed back, but NOT mirrored onto local Ad documents (no column for it yet).",
                      "type": "string"
                    },
                    "roasAverageFloor": {
                      "type": "number"
                    },
                    "sharedBudgetId": {
                      "description": "Google only. Echoed back when the campaign moved budgets; `budget` is then the budget it now uses.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "targetImpressionShare": {
                      "description": "Google only. Target impression share bidding (Search campaigns only): Google sets bids so the ads show in `location` for `percent` of eligible impressions.",
                      "properties": {
                        "location": {
                          "enum": [
                            "ANYWHERE_ON_PAGE",
                            "TOP_OF_PAGE",
                            "ABSOLUTE_TOP_OF_PAGE"
                          ],
                          "type": "string"
                        },
                        "maxCpc": {
                          "description": "Max CPC bid limit, in the account's currency units. Google requires it.",
                          "exclusiveMinimum": 0,
                          "type": "number"
                        },
                        "percent": {
                          "description": "Target share of impressions, in percent (65 = 65%). Sent to Google as location_fraction_micros (1% = 10,000).",
                          "exclusiveMinimum": 0,
                          "maximum": 100,
                          "type": "number"
                        }
                      },
                      "required": [
                        "location",
                        "maxCpc",
                        "percent"
                      ],
                      "type": "object"
                    },
                    "trackingUrlTemplate": {
                      "type": "string"
                    },
                    "updated": {
                      "description": "Local Ad documents mirrored. 0 on the empty-campaign path.",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update a campaign",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_campaign@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a26039b71ae18b7fe0e96b6d4350a10fa889b1f613ed1a3becfb9bb79255f0d2"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_campaigns_campaignid",
          "method": "PUT",
          "path": "/apis/v1/ads/campaigns/{campaignId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_campaigns_campaignid"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/ad-schedule": {
      "get": {
        "description": "Ad Campaigns. Read only. Shows the days and hours a Google campaign runs and its bid adjustments, optionally with performance by day and hour. The windows a Google campaign serves in, with the bid modifier on each, plus the criterion ids Google minted for them. An EMPTY `schedule` is meaningful and is not a failed lookup: Google has no \"all day\" criterion, so a campaign with no ad schedule serves around the clock.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_ad__83a9a8",
        "parameters": [
          {
            "description": "Numeric Google platform campaign id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Disambiguates the campaign id when the connection spans platforms.",
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "google"
              ],
              "type": "string"
            }
          },
          {
            "description": "Also return delivery by day of week and by hour. Costs one extra Google call.",
            "in": "query",
            "name": "includePerformance",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Trailing window for the performance split. Ignored when fromDate and toDate are both given.",
            "in": "query",
            "name": "windowDays",
            "required": false,
            "schema": {
              "default": 30,
              "maximum": 90,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Start of an explicit performance range (YYYY-MM-DD). Use together with toDate.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End of an explicit performance range (YYYY-MM-DD). Must be on or after fromDate.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "campaignId": {
                      "type": "string"
                    },
                    "performance": {
                      "description": "Only present when includePerformance=true.",
                      "properties": {
                        "byDayOfWeek": {
                          "description": "One entry per day that delivered, Monday first.",
                          "items": {
                            "properties": {
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "type": "number"
                              },
                              "cost": {
                                "description": "Account currency, not USD-normalized.",
                                "type": "number"
                              },
                              "dayOfWeek": {
                                "enum": [
                                  "MONDAY",
                                  "TUESDAY",
                                  "WEDNESDAY",
                                  "THURSDAY",
                                  "FRIDAY",
                                  "SATURDAY",
                                  "SUNDAY"
                                ],
                                "type": "string"
                              },
                              "impressions": {
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "byHour": {
                          "description": "One entry per hour that delivered, 0-23 in the account time zone.",
                          "items": {
                            "properties": {
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "type": "number"
                              },
                              "cost": {
                                "description": "Account currency, not USD-normalized.",
                                "type": "number"
                              },
                              "hour": {
                                "maximum": 23,
                                "minimum": 0,
                                "type": "integer"
                              },
                              "impressions": {
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "windowDays": {
                          "description": "The trailing window used, or null when an explicit fromDate/toDate range was given.",
                          "type": [
                            "integer",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    },
                    "schedule": {
                      "items": {
                        "description": "One ad schedule window as Google stores it. Half-open: it is exclusive of the end minute, so 09:00-12:00 and 12:00-17:00 are adjacent, not overlapping.",
                        "properties": {
                          "bidModifier": {
                            "description": "Bid adjustment for this window, 0.1-10.0. Null when the window runs at the campaign bid.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "criterionId": {
                            "description": "Google campaign criterion id. Changes whenever the window is rewritten, because Google cannot edit a schedule in place.",
                            "type": "string"
                          },
                          "dayOfWeek": {
                            "enum": [
                              "MONDAY",
                              "TUESDAY",
                              "WEDNESDAY",
                              "THURSDAY",
                              "FRIDAY",
                              "SATURDAY",
                              "SUNDAY"
                            ],
                            "type": "string"
                          },
                          "endHour": {
                            "description": "24 means midnight at the end of the day.",
                            "maximum": 24,
                            "minimum": 0,
                            "type": "integer"
                          },
                          "endMinute": {
                            "enum": [
                              0,
                              15,
                              30,
                              45
                            ],
                            "type": "integer"
                          },
                          "resourceName": {
                            "type": "string"
                          },
                          "startHour": {
                            "maximum": 23,
                            "minimum": 0,
                            "type": "integer"
                          },
                          "startMinute": {
                            "enum": [
                              0,
                              15,
                              30,
                              45
                            ],
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "servesAroundTheClock": {
                      "description": "True when the campaign carries no ad schedule at all, so it can serve at any time.",
                      "type": "boolean"
                    },
                    "stale": {
                      "description": "True when a quota-exhausted read served the last-good copy.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The campaign's ad schedule"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Read a campaign's ad schedule (dayparting)",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_campaign_ad_schedule@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "fb11e41dcc288d7ef3dd738766936a0b07d15beaa42aae4aed5747ee3910cded"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_ad__83a9a8",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/ad-schedule"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_ad__83a9a8"
      },
      "put": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Changes when a campaign delivers, and so when it spends. Replaces the days and hours a Google campaign runs, or clears them so it serves around the clock. This is a REPLACE, not a merge: windows you leave out stop serving. Send `schedule: []` to clear dayparting, which returns the campaign to serving around the clock. ### Rules Google rules are enforced here, so you get a named field instead of a criterion error: at most 6 windows per day\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_ad__83a9a8",
        "parameters": [
          {
            "description": "Numeric Google platform campaign id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "schedule": [
                  {
                    "dayOfWeek": "MONDAY",
                    "endHour": 17,
                    "startHour": 9
                  },
                  {
                    "dayOfWeek": "TUESDAY",
                    "endHour": 17,
                    "startHour": 9
                  },
                  {
                    "bidModifier": 1.5,
                    "dayOfWeek": "WEDNESDAY",
                    "endHour": 12,
                    "startHour": 9
                  },
                  {
                    "dayOfWeek": "WEDNESDAY",
                    "endHour": 17,
                    "startHour": 12
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "schedule": {
                    "description": "The complete set of windows. Required, so clearing the schedule is always deliberate rather than an omission.",
                    "items": {
                      "properties": {
                        "bidModifier": {
                          "description": "Bid adjustment for this window. Null runs it at the campaign bid.",
                          "maximum": 10,
                          "minimum": 0.1,
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "dayOfWeek": {
                          "enum": [
                            "MONDAY",
                            "TUESDAY",
                            "WEDNESDAY",
                            "THURSDAY",
                            "FRIDAY",
                            "SATURDAY",
                            "SUNDAY"
                          ],
                          "type": "string"
                        },
                        "endHour": {
                          "description": "24 means midnight at the end of the day.",
                          "maximum": 24,
                          "minimum": 0,
                          "type": "integer"
                        },
                        "endMinute": {
                          "default": 0,
                          "description": "Quarter-hours only. Must be 0 when endHour is 24.",
                          "enum": [
                            0,
                            15,
                            30,
                            45
                          ],
                          "type": "integer"
                        },
                        "startHour": {
                          "maximum": 23,
                          "minimum": 0,
                          "type": "integer"
                        },
                        "startMinute": {
                          "default": 0,
                          "description": "Quarter-hours only.",
                          "enum": [
                            0,
                            15,
                            30,
                            45
                          ],
                          "type": "integer"
                        }
                      },
                      "required": [
                        "dayOfWeek",
                        "endHour",
                        "startHour"
                      ],
                      "type": "object"
                    },
                    "maxItems": 42,
                    "type": "array"
                  }
                },
                "required": [
                  "schedule"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "campaignId": {
                      "type": "string"
                    },
                    "schedule": {
                      "items": {
                        "description": "One ad schedule window as Google stores it. Half-open: it is exclusive of the end minute, so 09:00-12:00 and 12:00-17:00 are adjacent, not overlapping.",
                        "properties": {
                          "bidModifier": {
                            "description": "Bid adjustment for this window, 0.1-10.0. Null when the window runs at the campaign bid.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "criterionId": {
                            "description": "Google campaign criterion id. Changes whenever the window is rewritten, because Google cannot edit a schedule in place.",
                            "type": "string"
                          },
                          "dayOfWeek": {
                            "enum": [
                              "MONDAY",
                              "TUESDAY",
                              "WEDNESDAY",
                              "THURSDAY",
                              "FRIDAY",
                              "SATURDAY",
                              "SUNDAY"
                            ],
                            "type": "string"
                          },
                          "endHour": {
                            "description": "24 means midnight at the end of the day.",
                            "maximum": 24,
                            "minimum": 0,
                            "type": "integer"
                          },
                          "endMinute": {
                            "enum": [
                              0,
                              15,
                              30,
                              45
                            ],
                            "type": "integer"
                          },
                          "resourceName": {
                            "type": "string"
                          },
                          "startHour": {
                            "maximum": 23,
                            "minimum": 0,
                            "type": "integer"
                          },
                          "startMinute": {
                            "enum": [
                              0,
                              15,
                              30,
                              45
                            ],
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "servesAroundTheClock": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The schedule as Google stored it"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Replace a campaign's ad schedule (dayparting)",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_campaign_ad_schedule@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6cd3aa3ea59a62fa1adb547db3b60eb009d06529026e51fec4b997d4dfef0854"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_ad__83a9a8",
          "method": "PUT",
          "path": "/apis/v1/ads/campaigns/{campaignId}/ad-schedule"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_campaigns_campaignid_ad__83a9a8"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/analytics": {
      "get": {
        "description": "Ad Insights. Read only. Returns a campaign's performance summary and daily timeline, with optional breakdowns by age, gender and other audience dimensions. One call returns analytics for a whole campaign: summary metrics a daily timeline over the requested date range (summed across the campaign's ads) optional demographic breakdowns\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_analytics",
        "parameters": [
          {
            "description": "Platform campaign id (platformCampaignId).",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Disambiguate when the campaign id exists across platforms (e.g. facebook, instagram).",
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start of date range (YYYY-MM-DD). Defaults to 90 days ago.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End of date range (YYYY-MM-DD). Defaults to today. Max 730-day range.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Comma-separated breakdown dimensions. Meta: age, gender, country, publisher_platform, device_platform, region, platform_position, impression_device, video_asset, image_asset, body_asset, title_asset.",
            "in": "query",
            "name": "breakdowns",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "analytics": {
                      "properties": {
                        "breakdownDroppedMetrics": {
                          "additionalProperties": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "description": "TikTok only: TikTok metric names TikTok refused for a breakdown, keyed by the requested breakdown (e.g. total_purchase and total_purchase_value have no relation to platform, ac or language). Absent when no metric was refused.",
                          "type": "object"
                        },
                        "breakdownErrors": {
                          "description": "TikTok only: breakdowns the platform failed to return (rate limit, permission, rejected query). Each one is an empty array under breakdowns; summary and daily are unaffected. Absent when every breakdown answered.",
                          "items": {
                            "properties": {
                              "breakdown": {
                                "type": "string"
                              },
                              "message": {
                                "description": "The platform's error message.",
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "breakdownHints": {
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "Guidance for some names in unsupportedBreakdowns, keyed by that name (e.g. placement on Meta points at publisher_platform and platform_position; platform_position on TikTok points at placement). Absent when no unsupported name has a hint.",
                          "type": "object"
                        },
                        "breakdowns": {
                          "additionalProperties": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "description": "Requested demographic breakdowns, keyed by dimension. Fetched live from the platform per request and never stored, so these rows can carry fields the stored `summary` and `daily` series do not.",
                          "type": "object"
                        },
                        "breakdownsRange": {
                          "description": "TikTok only, present when the requested range is longer than the 365 days TikTok serves per breakdown: the window the breakdowns cover (the last 365 days of the range). summary and daily still cover the full range.",
                          "properties": {
                            "fromDate": {
                              "format": "date",
                              "type": "string"
                            },
                            "toDate": {
                              "format": "date",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "daily": {
                          "items": {
                            "properties": {
                              "actionValues": {
                                "additionalProperties": true,
                                "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                "type": "object"
                              },
                              "actions": {
                                "additionalProperties": true,
                                "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                "type": "object"
                              },
                              "allConversions": {
                                "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                "type": "number"
                              },
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                "type": "number"
                              },
                              "costPerAction": {
                                "additionalProperties": true,
                                "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                "type": "object"
                              },
                              "costPerConversion": {
                                "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                "type": "number"
                              },
                              "costPerThruplay": {
                                "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                "type": "number"
                              },
                              "cpc": {
                                "description": "Cost per click",
                                "type": "number"
                              },
                              "cpm": {
                                "description": "Cost per 1000 impressions",
                                "type": "number"
                              },
                              "ctr": {
                                "description": "Click-through rate (%)",
                                "type": "number"
                              },
                              "date": {
                                "format": "date",
                                "type": "string"
                              },
                              "engagement": {
                                "type": "integer"
                              },
                              "engagementBreakdown": {
                                "additionalProperties": true,
                                "description": "The single `engagement` total, split into the interactions behind it.",
                                "type": "object"
                              },
                              "funnel": {
                                "additionalProperties": true,
                                "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                "type": "object"
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "inlineLinkClickCtr": {
                                "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "inlineLinkClicks": {
                                "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                "type": "integer"
                              },
                              "lastSyncedAt": {
                                "description": "Present on individual ads only, not on campaign aggregations",
                                "format": "date-time",
                                "type": "string"
                              },
                              "outboundClicks": {
                                "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                "type": "integer"
                              },
                              "outboundClicksCtr": {
                                "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "purchaseValue": {
                                "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                "type": "number"
                              },
                              "reach": {
                                "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                "type": "integer"
                              },
                              "roas": {
                                "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                "type": "number"
                              },
                              "spend": {
                                "type": "number"
                              },
                              "uniqueClicks": {
                                "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                "type": "integer"
                              },
                              "uniqueCtr": {
                                "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                "type": "number"
                              },
                              "video2SecWatchedActions": {
                                "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                "type": "integer"
                              },
                              "video30SecWatchedActions": {
                                "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                "type": "integer"
                              },
                              "video6SecFocusedViews": {
                                "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                "type": "integer"
                              },
                              "video6SecWatchedActions": {
                                "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                "type": "integer"
                              },
                              "videoAvgTimeWatchedActions": {
                                "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                "type": "number"
                              },
                              "videoP100WatchedActions": {
                                "description": "Views reaching 100% of the video's length.",
                                "type": "integer"
                              },
                              "videoP25WatchedActions": {
                                "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                "type": "integer"
                              },
                              "videoP50WatchedActions": {
                                "description": "Views reaching 50% of the video's length.",
                                "type": "integer"
                              },
                              "videoP75WatchedActions": {
                                "description": "Views reaching 75% of the video's length.",
                                "type": "integer"
                              },
                              "videoP95WatchedActions": {
                                "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                "type": "integer"
                              },
                              "videoPlayActions": {
                                "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                "type": "integer"
                              },
                              "videoThruplayWatchedActions": {
                                "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "impressionShareCache": {
                          "description": "Google only. Cache status of the single date-range impression-share query.",
                          "properties": {
                            "cachedAt": {
                              "format": "date-time",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "stale": {
                              "type": "boolean"
                            }
                          },
                          "type": "object"
                        },
                        "summary": {
                          "properties": {
                            "actionValues": {
                              "additionalProperties": {
                                "type": "number"
                              },
                              "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                              "type": "object"
                            },
                            "actions": {
                              "additionalProperties": {
                                "type": "integer"
                              },
                              "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                              "type": "object"
                            },
                            "allConversions": {
                              "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                              "type": "number"
                            },
                            "clicks": {
                              "type": "integer"
                            },
                            "conversions": {
                              "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                              "type": "number"
                            },
                            "costPerAction": {
                              "additionalProperties": {
                                "type": "number"
                              },
                              "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                              "type": "object"
                            },
                            "costPerConversion": {
                              "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                              "type": "number"
                            },
                            "costPerThruplay": {
                              "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                              "type": "number"
                            },
                            "cpc": {
                              "description": "Cost per click",
                              "type": "number"
                            },
                            "cpm": {
                              "description": "Cost per 1000 impressions",
                              "type": "number"
                            },
                            "ctr": {
                              "description": "Click-through rate (%)",
                              "type": "number"
                            },
                            "engagement": {
                              "type": "integer"
                            },
                            "engagementBreakdown": {
                              "description": "The single `engagement` total, split into the interactions behind it.",
                              "properties": {
                                "comments": {
                                  "description": "Comments on the ad's post.",
                                  "type": "integer"
                                },
                                "linkClicks": {
                                  "description": "Attributed link clicks (`link_click`). This is the attribution-window count, which differs from the in-session count in the sibling `inlineLinkClicks` field.",
                                  "type": "integer"
                                },
                                "pageEngagement": {
                                  "description": "Meta's own page-engagement total (`page_engagement`). Meta-only.",
                                  "type": "integer"
                                },
                                "pageLikes": {
                                  "description": "New Page likes attributed to the ad (`like`).",
                                  "type": "integer"
                                },
                                "postEngagement": {
                                  "description": "Meta's own post-engagement total (`post_engagement`). Meta-only.",
                                  "type": "integer"
                                },
                                "reactions": {
                                  "description": "Reactions on the ad's post (`post_reaction`). For TikTok these are its paid likes.",
                                  "type": "integer"
                                },
                                "saves": {
                                  "description": "Saves of the ad's post (`onsite_conversion.post_save`).",
                                  "type": "integer"
                                },
                                "shares": {
                                  "description": "Shares of the ad's post. Meta reports these under the action type literally named `post`; TikTok under `share`.",
                                  "type": "integer"
                                },
                                "videoViews": {
                                  "description": "Video views, from the `video_view` action. Meta counts a 3-second view; LinkedIn's own `videoViews` threshold (2 continuous seconds, or 25% of the video) lands under the same key, so compare across platforms with care.",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "funnel": {
                              "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                              "properties": {
                                "appInstalls": {
                                  "description": "Mobile app installs attributed to the ad.",
                                  "type": "integer"
                                },
                                "cartAdds": {
                                  "description": "Adds to cart (Meta `AddToCart` pixel event).",
                                  "type": "integer"
                                },
                                "checkoutsInitiated": {
                                  "description": "Checkouts started (Meta `InitiateCheckout` pixel event).",
                                  "type": "integer"
                                },
                                "contentViews": {
                                  "description": "Content views (Meta `ViewContent` pixel event).",
                                  "type": "integer"
                                },
                                "landingPageViews": {
                                  "description": "Landing page views: the visitor actually loaded the destination, unlike a link click. Meta `landing_page_view`.",
                                  "type": "integer"
                                },
                                "leads": {
                                  "description": "Leads, from either the website pixel or an instant form, whichever the ad uses.",
                                  "type": "integer"
                                },
                                "messagingConversationsStarted": {
                                  "description": "Messaging conversations started within 7 days, the headline metric for click-to-WhatsApp and click-to-Messenger ads.",
                                  "type": "integer"
                                },
                                "messagingFirstReplies": {
                                  "description": "Messaging threads where the person sent a first reply.",
                                  "type": "integer"
                                },
                                "paymentInfoAdds": {
                                  "description": "Payment details added at checkout (Meta `AddPaymentInfo` pixel event).",
                                  "type": "integer"
                                },
                                "purchases": {
                                  "description": "Purchases. Pair with `purchaseValue` for revenue.",
                                  "type": "integer"
                                },
                                "registrationsCompleted": {
                                  "description": "Completed registrations (Meta `CompleteRegistration` pixel event).",
                                  "type": "integer"
                                },
                                "searches": {
                                  "description": "On-site searches (Meta `Search` pixel event).",
                                  "type": "integer"
                                },
                                "wishlistAdds": {
                                  "description": "Adds to wishlist (Meta `AddToWishlist` pixel event).",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "impressions": {
                              "type": "integer"
                            },
                            "inlineLinkClickCtr": {
                              "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                              "type": "number"
                            },
                            "inlineLinkClicks": {
                              "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                              "type": "integer"
                            },
                            "lastSyncedAt": {
                              "description": "Present on individual ads only, not on campaign aggregations",
                              "format": "date-time",
                              "type": "string"
                            },
                            "outboundClicks": {
                              "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                              "type": "integer"
                            },
                            "outboundClicksCtr": {
                              "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                              "type": "number"
                            },
                            "purchaseValue": {
                              "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                              "type": "number"
                            },
                            "reach": {
                              "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                              "type": "integer"
                            },
                            "roas": {
                              "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                              "type": "number"
                            },
                            "searchAbsoluteTopImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "searchBudgetLostImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "searchImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "searchRankLostImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "searchTopImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "spend": {
                              "type": "number"
                            },
                            "uniqueClicks": {
                              "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                              "type": "integer"
                            },
                            "uniqueCtr": {
                              "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                              "type": "number"
                            },
                            "video2SecWatchedActions": {
                              "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                              "type": "integer"
                            },
                            "video30SecWatchedActions": {
                              "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                              "type": "integer"
                            },
                            "video6SecFocusedViews": {
                              "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                              "type": "integer"
                            },
                            "video6SecWatchedActions": {
                              "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                              "type": "integer"
                            },
                            "videoAvgTimeWatchedActions": {
                              "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                              "type": "number"
                            },
                            "videoP100WatchedActions": {
                              "description": "Views reaching 100% of the video's length.",
                              "type": "integer"
                            },
                            "videoP25WatchedActions": {
                              "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                              "type": "integer"
                            },
                            "videoP50WatchedActions": {
                              "description": "Views reaching 50% of the video's length.",
                              "type": "integer"
                            },
                            "videoP75WatchedActions": {
                              "description": "Views reaching 75% of the video's length.",
                              "type": "integer"
                            },
                            "videoP95WatchedActions": {
                              "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                              "type": "integer"
                            },
                            "videoPlayActions": {
                              "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                              "type": "integer"
                            },
                            "videoThruplayWatchedActions": {
                              "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                              "type": "integer"
                            }
                          },
                          "type": "object"
                        },
                        "unsupportedBreakdowns": {
                          "description": "Requested breakdowns this platform cannot break down by (e.g. region on TikTok, any breakdown on Google). Absent when every requested breakdown is supported.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    },
                    "backfillPending": {
                      "description": "Meta only. Present and true while historical data is being backfilled.",
                      "type": "boolean"
                    },
                    "campaign": {
                      "properties": {
                        "budget": {
                          "anyOf": [
                            {
                              "description": "Budget amount in the ad account's native currency (see the campaign's `currency` field for the code).",
                              "properties": {
                                "amount": {
                                  "type": "number"
                                },
                                "amountMicros": {
                                  "description": "Google only. Exact decimal micros; DAILY uses amount_micros and CUSTOM_PERIOD uses total_amount_micros.",
                                  "pattern": "^\\d+$",
                                  "type": "string"
                                },
                                "deliveryMethod": {
                                  "description": "Google only. campaign_budget.delivery_method, typically STANDARD, or null when unavailable.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "explicitlyShared": {
                                  "description": "Google only. True for a shared budget; null when unavailable. Shared writes require allowSharedBudgetUpdate=true; unknown sharing status cannot be overridden.",
                                  "type": [
                                    "boolean",
                                    "null"
                                  ]
                                },
                                "resourceName": {
                                  "description": "Google only. campaign_budget.resource_name, or null when unavailable.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "type": {
                                  "enum": [
                                    "daily",
                                    "lifetime"
                                  ],
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "type"
                              ],
                              "type": "object"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Google only. Latest synced campaign budget, or null before sync."
                        },
                        "currency": {
                          "description": "ISO 4217 code of the ad account (e.g. USD, THB). All money values in `summary` and `daily` are in this currency.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platform": {
                          "type": "string"
                        },
                        "status": {
                          "description": "The platform's own campaign status in its vocabulary (Google ENABLED / PAUSED / REMOVED, Meta ACTIVE / PAUSED, ...), the same value as platformCampaignStatus on /apis/v1/ads/campaigns and /apis/v1/ads/tree.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign analytics"
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "analytics": {
                      "properties": {
                        "breakdownDroppedMetrics": {
                          "additionalProperties": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "description": "TikTok only: TikTok metric names TikTok refused for a breakdown, keyed by the requested breakdown (e.g. total_purchase and total_purchase_value have no relation to platform, ac or language). Absent when no metric was refused.",
                          "type": "object"
                        },
                        "breakdownErrors": {
                          "description": "TikTok only: breakdowns the platform failed to return (rate limit, permission, rejected query). Each one is an empty array under breakdowns; summary and daily are unaffected. Absent when every breakdown answered.",
                          "items": {
                            "properties": {
                              "breakdown": {
                                "type": "string"
                              },
                              "message": {
                                "description": "The platform's error message.",
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "breakdownHints": {
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "Guidance for some names in unsupportedBreakdowns, keyed by that name (e.g. placement on Meta points at publisher_platform and platform_position; platform_position on TikTok points at placement). Absent when no unsupported name has a hint.",
                          "type": "object"
                        },
                        "breakdowns": {
                          "additionalProperties": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "description": "Requested demographic breakdowns, keyed by dimension. Fetched live from the platform per request and never stored, so these rows can carry fields the stored `summary` and `daily` series do not.",
                          "type": "object"
                        },
                        "breakdownsRange": {
                          "description": "TikTok only, present when the requested range is longer than the 365 days TikTok serves per breakdown: the window the breakdowns cover (the last 365 days of the range). summary and daily still cover the full range.",
                          "properties": {
                            "fromDate": {
                              "format": "date",
                              "type": "string"
                            },
                            "toDate": {
                              "format": "date",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "daily": {
                          "items": {
                            "properties": {
                              "actionValues": {
                                "additionalProperties": true,
                                "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                "type": "object"
                              },
                              "actions": {
                                "additionalProperties": true,
                                "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                "type": "object"
                              },
                              "allConversions": {
                                "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                "type": "number"
                              },
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                "type": "number"
                              },
                              "costPerAction": {
                                "additionalProperties": true,
                                "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                "type": "object"
                              },
                              "costPerConversion": {
                                "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                "type": "number"
                              },
                              "costPerThruplay": {
                                "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                "type": "number"
                              },
                              "cpc": {
                                "description": "Cost per click",
                                "type": "number"
                              },
                              "cpm": {
                                "description": "Cost per 1000 impressions",
                                "type": "number"
                              },
                              "ctr": {
                                "description": "Click-through rate (%)",
                                "type": "number"
                              },
                              "date": {
                                "format": "date",
                                "type": "string"
                              },
                              "engagement": {
                                "type": "integer"
                              },
                              "engagementBreakdown": {
                                "additionalProperties": true,
                                "description": "The single `engagement` total, split into the interactions behind it.",
                                "type": "object"
                              },
                              "funnel": {
                                "additionalProperties": true,
                                "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                "type": "object"
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "inlineLinkClickCtr": {
                                "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "inlineLinkClicks": {
                                "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                "type": "integer"
                              },
                              "lastSyncedAt": {
                                "description": "Present on individual ads only, not on campaign aggregations",
                                "format": "date-time",
                                "type": "string"
                              },
                              "outboundClicks": {
                                "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                "type": "integer"
                              },
                              "outboundClicksCtr": {
                                "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "purchaseValue": {
                                "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                "type": "number"
                              },
                              "reach": {
                                "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                "type": "integer"
                              },
                              "roas": {
                                "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                "type": "number"
                              },
                              "spend": {
                                "type": "number"
                              },
                              "uniqueClicks": {
                                "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                "type": "integer"
                              },
                              "uniqueCtr": {
                                "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                "type": "number"
                              },
                              "video2SecWatchedActions": {
                                "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                "type": "integer"
                              },
                              "video30SecWatchedActions": {
                                "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                "type": "integer"
                              },
                              "video6SecFocusedViews": {
                                "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                "type": "integer"
                              },
                              "video6SecWatchedActions": {
                                "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                "type": "integer"
                              },
                              "videoAvgTimeWatchedActions": {
                                "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                "type": "number"
                              },
                              "videoP100WatchedActions": {
                                "description": "Views reaching 100% of the video's length.",
                                "type": "integer"
                              },
                              "videoP25WatchedActions": {
                                "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                "type": "integer"
                              },
                              "videoP50WatchedActions": {
                                "description": "Views reaching 50% of the video's length.",
                                "type": "integer"
                              },
                              "videoP75WatchedActions": {
                                "description": "Views reaching 75% of the video's length.",
                                "type": "integer"
                              },
                              "videoP95WatchedActions": {
                                "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                "type": "integer"
                              },
                              "videoPlayActions": {
                                "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                "type": "integer"
                              },
                              "videoThruplayWatchedActions": {
                                "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "impressionShareCache": {
                          "description": "Google only. Cache status of the single date-range impression-share query.",
                          "properties": {
                            "cachedAt": {
                              "format": "date-time",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "stale": {
                              "type": "boolean"
                            }
                          },
                          "type": "object"
                        },
                        "summary": {
                          "properties": {
                            "actionValues": {
                              "additionalProperties": {
                                "type": "number"
                              },
                              "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                              "type": "object"
                            },
                            "actions": {
                              "additionalProperties": {
                                "type": "integer"
                              },
                              "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                              "type": "object"
                            },
                            "allConversions": {
                              "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                              "type": "number"
                            },
                            "clicks": {
                              "type": "integer"
                            },
                            "conversions": {
                              "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                              "type": "number"
                            },
                            "costPerAction": {
                              "additionalProperties": {
                                "type": "number"
                              },
                              "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                              "type": "object"
                            },
                            "costPerConversion": {
                              "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                              "type": "number"
                            },
                            "costPerThruplay": {
                              "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                              "type": "number"
                            },
                            "cpc": {
                              "description": "Cost per click",
                              "type": "number"
                            },
                            "cpm": {
                              "description": "Cost per 1000 impressions",
                              "type": "number"
                            },
                            "ctr": {
                              "description": "Click-through rate (%)",
                              "type": "number"
                            },
                            "engagement": {
                              "type": "integer"
                            },
                            "engagementBreakdown": {
                              "description": "The single `engagement` total, split into the interactions behind it.",
                              "properties": {
                                "comments": {
                                  "description": "Comments on the ad's post.",
                                  "type": "integer"
                                },
                                "linkClicks": {
                                  "description": "Attributed link clicks (`link_click`). This is the attribution-window count, which differs from the in-session count in the sibling `inlineLinkClicks` field.",
                                  "type": "integer"
                                },
                                "pageEngagement": {
                                  "description": "Meta's own page-engagement total (`page_engagement`). Meta-only.",
                                  "type": "integer"
                                },
                                "pageLikes": {
                                  "description": "New Page likes attributed to the ad (`like`).",
                                  "type": "integer"
                                },
                                "postEngagement": {
                                  "description": "Meta's own post-engagement total (`post_engagement`). Meta-only.",
                                  "type": "integer"
                                },
                                "reactions": {
                                  "description": "Reactions on the ad's post (`post_reaction`). For TikTok these are its paid likes.",
                                  "type": "integer"
                                },
                                "saves": {
                                  "description": "Saves of the ad's post (`onsite_conversion.post_save`).",
                                  "type": "integer"
                                },
                                "shares": {
                                  "description": "Shares of the ad's post. Meta reports these under the action type literally named `post`; TikTok under `share`.",
                                  "type": "integer"
                                },
                                "videoViews": {
                                  "description": "Video views, from the `video_view` action. Meta counts a 3-second view; LinkedIn's own `videoViews` threshold (2 continuous seconds, or 25% of the video) lands under the same key, so compare across platforms with care.",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "funnel": {
                              "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                              "properties": {
                                "appInstalls": {
                                  "description": "Mobile app installs attributed to the ad.",
                                  "type": "integer"
                                },
                                "cartAdds": {
                                  "description": "Adds to cart (Meta `AddToCart` pixel event).",
                                  "type": "integer"
                                },
                                "checkoutsInitiated": {
                                  "description": "Checkouts started (Meta `InitiateCheckout` pixel event).",
                                  "type": "integer"
                                },
                                "contentViews": {
                                  "description": "Content views (Meta `ViewContent` pixel event).",
                                  "type": "integer"
                                },
                                "landingPageViews": {
                                  "description": "Landing page views: the visitor actually loaded the destination, unlike a link click. Meta `landing_page_view`.",
                                  "type": "integer"
                                },
                                "leads": {
                                  "description": "Leads, from either the website pixel or an instant form, whichever the ad uses.",
                                  "type": "integer"
                                },
                                "messagingConversationsStarted": {
                                  "description": "Messaging conversations started within 7 days, the headline metric for click-to-WhatsApp and click-to-Messenger ads.",
                                  "type": "integer"
                                },
                                "messagingFirstReplies": {
                                  "description": "Messaging threads where the person sent a first reply.",
                                  "type": "integer"
                                },
                                "paymentInfoAdds": {
                                  "description": "Payment details added at checkout (Meta `AddPaymentInfo` pixel event).",
                                  "type": "integer"
                                },
                                "purchases": {
                                  "description": "Purchases. Pair with `purchaseValue` for revenue.",
                                  "type": "integer"
                                },
                                "registrationsCompleted": {
                                  "description": "Completed registrations (Meta `CompleteRegistration` pixel event).",
                                  "type": "integer"
                                },
                                "searches": {
                                  "description": "On-site searches (Meta `Search` pixel event).",
                                  "type": "integer"
                                },
                                "wishlistAdds": {
                                  "description": "Adds to wishlist (Meta `AddToWishlist` pixel event).",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "impressions": {
                              "type": "integer"
                            },
                            "inlineLinkClickCtr": {
                              "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                              "type": "number"
                            },
                            "inlineLinkClicks": {
                              "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                              "type": "integer"
                            },
                            "lastSyncedAt": {
                              "description": "Present on individual ads only, not on campaign aggregations",
                              "format": "date-time",
                              "type": "string"
                            },
                            "outboundClicks": {
                              "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                              "type": "integer"
                            },
                            "outboundClicksCtr": {
                              "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                              "type": "number"
                            },
                            "purchaseValue": {
                              "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                              "type": "number"
                            },
                            "reach": {
                              "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                              "type": "integer"
                            },
                            "roas": {
                              "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                              "type": "number"
                            },
                            "searchAbsoluteTopImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "searchBudgetLostImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "searchImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "searchRankLostImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "searchTopImpressionShare": {
                              "description": "Google only. Date-range ratio, not a percentage. Null when unavailable; Google's threshold sentinel values are preserved.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "spend": {
                              "type": "number"
                            },
                            "uniqueClicks": {
                              "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                              "type": "integer"
                            },
                            "uniqueCtr": {
                              "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                              "type": "number"
                            },
                            "video2SecWatchedActions": {
                              "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                              "type": "integer"
                            },
                            "video30SecWatchedActions": {
                              "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                              "type": "integer"
                            },
                            "video6SecFocusedViews": {
                              "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                              "type": "integer"
                            },
                            "video6SecWatchedActions": {
                              "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                              "type": "integer"
                            },
                            "videoAvgTimeWatchedActions": {
                              "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                              "type": "number"
                            },
                            "videoP100WatchedActions": {
                              "description": "Views reaching 100% of the video's length.",
                              "type": "integer"
                            },
                            "videoP25WatchedActions": {
                              "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                              "type": "integer"
                            },
                            "videoP50WatchedActions": {
                              "description": "Views reaching 50% of the video's length.",
                              "type": "integer"
                            },
                            "videoP75WatchedActions": {
                              "description": "Views reaching 75% of the video's length.",
                              "type": "integer"
                            },
                            "videoP95WatchedActions": {
                              "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                              "type": "integer"
                            },
                            "videoPlayActions": {
                              "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                              "type": "integer"
                            },
                            "videoThruplayWatchedActions": {
                              "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                              "type": "integer"
                            }
                          },
                          "type": "object"
                        },
                        "unsupportedBreakdowns": {
                          "description": "Requested breakdowns this platform cannot break down by (e.g. region on TikTok, any breakdown on Google). Absent when every requested breakdown is supported.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    },
                    "backfillPending": {
                      "description": "Always true on this response. Part of the requested range is still being backfilled; retry until the request returns 200.",
                      "type": "boolean"
                    },
                    "campaign": {
                      "properties": {
                        "budget": {
                          "anyOf": [
                            {
                              "description": "Budget amount in the ad account's native currency (see the campaign's `currency` field for the code).",
                              "properties": {
                                "amount": {
                                  "type": "number"
                                },
                                "amountMicros": {
                                  "description": "Google only. Exact decimal micros; DAILY uses amount_micros and CUSTOM_PERIOD uses total_amount_micros.",
                                  "pattern": "^\\d+$",
                                  "type": "string"
                                },
                                "deliveryMethod": {
                                  "description": "Google only. campaign_budget.delivery_method, typically STANDARD, or null when unavailable.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "explicitlyShared": {
                                  "description": "Google only. True for a shared budget; null when unavailable. Shared writes require allowSharedBudgetUpdate=true; unknown sharing status cannot be overridden.",
                                  "type": [
                                    "boolean",
                                    "null"
                                  ]
                                },
                                "resourceName": {
                                  "description": "Google only. campaign_budget.resource_name, or null when unavailable.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "type": {
                                  "enum": [
                                    "daily",
                                    "lifetime"
                                  ],
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "type"
                              ],
                              "type": "object"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Google only. Latest synced campaign budget, or null before sync."
                        },
                        "currency": {
                          "description": "ISO 4217 code of the ad account (e.g. USD, THB). All money values in `summary` and `daily` are in this currency.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platform": {
                          "type": "string"
                        },
                        "status": {
                          "description": "The platform's own campaign status in its vocabulary (Google ENABLED / PAUSED / REMOVED, Meta ACTIVE / PAUSED, ...), the same value as platformCampaignStatus on /apis/v1/ads/campaigns and /apis/v1/ads/tree.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "required": [
                    "backfillPending"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Meta only. Historical data is incomplete and backfill remains pending."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get campaign analytics",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_campaign_analytics@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6b4542d14ec725b2194dd6d51a514b2806c0d32cd83fa7de02793f52ad9ba3e5"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_analytics",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/analytics"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_analytics"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/asset-groups": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists a Performance Max campaign's asset groups with their linked text, image and YouTube assets. campaignId is the platform campaign id returned by creation or the campaign list. The campaign must be visible to the caller. ### Caching Uses a 10-minute cache, with the last successful response served as stale when Google quota is exhausted. ### What is left out\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_ass_bb4817",
        "parameters": [
          {
            "description": "Google Ads campaign id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "assetGroups": {
                      "items": {
                        "properties": {
                          "adStrength": {
                            "description": "Google ad strength, such as POOR, AVERAGE, GOOD or EXCELLENT.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "assets": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "campaignId": {
                            "type": "string"
                          },
                          "finalMobileUrls": {
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "finalUrls": {
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "id": {
                            "description": "Stable Google asset group id. Use it in the asset-group endpoints below.",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "path1": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "path2": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "primaryStatus": {
                            "description": "Why the group is or is not serving, such as ELIGIBLE, PAUSED or NOT_ELIGIBLE.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "primaryStatusReasons": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "resourceName": {
                            "description": "customers/{customerId}/assetGroups/{assetGroupId}",
                            "type": "string"
                          },
                          "status": {
                            "description": "Asset-group status on Google. Campaign status independently controls delivery.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "adStrength",
                          "assets",
                          "campaignId",
                          "finalMobileUrls",
                          "finalUrls",
                          "id",
                          "name",
                          "path1",
                          "path2",
                          "primaryStatus",
                          "primaryStatusReasons",
                          "resourceName",
                          "status"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "cachedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "stale": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "assetGroups",
                    "cachedAt",
                    "stale"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Asset groups and linked assets."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List Performance Max asset groups",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_google_asset_groups@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "9ed8b27b67d7e5428f907626090de0b10deec065785aa3ab3f4d18d6ddd1569b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_ass_bb4817",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/asset-groups"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_ass_bb4817"
      },
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates a Performance Max asset group that can start serving. validateOnly=true checks the request without acting and needs no confirmation. Adds an asset group with its assets and optional product targeting to a Performance Max campaign, or just validates it without creating anything. The group, any new assets, their links and an optional listing-group tree are created in one atomic request, so Google checks the asset minimums (for non-retail campaigns) against the whole set. Created PAUSED unless status is ENABLED.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_campaigns_campaignid_as_bb4817",
        "parameters": [
          {
            "description": "Google Ads campaign id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "assets": [
                  {
                    "fieldType": "HEADLINE",
                    "text": "Shoes for every run"
                  },
                  {
                    "asset": "customers/9122445560/assets/352426364803",
                    "fieldType": "LOGO"
                  }
                ],
                "connectionId": "adc_7f3k2m9q",
                "finalUrls": [
                  "https://example.com/shoes"
                ],
                "name": "Running shoes"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "assets": {
                    "items": {
                      "description": "Link one asset to the asset group. Send exactly one of asset (an existing asset), text, imageUrl or youtubeVideoId (new content, created in the same request).",
                      "properties": {
                        "asset": {
                          "description": "Existing asset id or resource name customers/{customerId}/assets/{assetId}. Must belong to the campaign's ad account.",
                          "type": "string"
                        },
                        "fieldType": {
                          "description": "Google AssetFieldType, such as HEADLINE, LONG_HEADLINE, DESCRIPTION, BUSINESS_NAME, MARKETING_IMAGE, SQUARE_MARKETING_IMAGE, PORTRAIT_MARKETING_IMAGE, LOGO, LANDSCAPE_LOGO or YOUTUBE_VIDEO.",
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Public http(s) image. Links as an image role or LOGO / LANDSCAPE_LOGO.",
                          "format": "uri",
                          "type": "string"
                        },
                        "text": {
                          "description": "Text assets link as HEADLINE, LONG_HEADLINE, DESCRIPTION or BUSINESS_NAME.",
                          "maxLength": 90,
                          "type": "string"
                        },
                        "youtubeVideoId": {
                          "description": "Links as YOUTUBE_VIDEO.",
                          "pattern": "^[A-Za-z0-9_-]{11}$",
                          "type": "string"
                        }
                      },
                      "required": [
                        "fieldType"
                      ],
                      "type": "object"
                    },
                    "maxItems": 100,
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "finalMobileUrls": {
                    "items": {
                      "format": "uri",
                      "type": "string"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  },
                  "finalUrls": {
                    "items": {
                      "format": "uri",
                      "type": "string"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  },
                  "listingGroupFilter": {
                    "description": "The root of a Performance Max retail listing-group tree (listing source SHOPPING). No children targets all products. Requires a campaign linked to Merchant Center.",
                    "properties": {
                      "children": {
                        "items": {
                          "properties": {
                            "children": {
                              "description": "Makes the node a subdivision. Children share one dimension (and level or index) and include exactly one everything-else node.",
                              "items": {
                                "description": "Same shape as its parent.",
                                "type": "object"
                              },
                              "minItems": 2,
                              "type": "array"
                            },
                            "dimension": {
                              "description": "Exactly one key. Omit the value (for example { productBrand: {} }) for the everything-else node of that level.",
                              "properties": {
                                "productBrand": {
                                  "properties": {
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "productCategory": {
                                  "properties": {
                                    "categoryId": {
                                      "description": "Google product category id.",
                                      "type": "string"
                                    },
                                    "level": {
                                      "enum": [
                                        "LEVEL1",
                                        "LEVEL2",
                                        "LEVEL3",
                                        "LEVEL4",
                                        "LEVEL5"
                                      ],
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "level"
                                  ],
                                  "type": "object"
                                },
                                "productChannel": {
                                  "properties": {
                                    "channel": {
                                      "enum": [
                                        "ONLINE",
                                        "LOCAL"
                                      ],
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "productCondition": {
                                  "properties": {
                                    "condition": {
                                      "enum": [
                                        "NEW",
                                        "REFURBISHED",
                                        "USED"
                                      ],
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "productCustomAttribute": {
                                  "properties": {
                                    "index": {
                                      "enum": [
                                        "INDEX0",
                                        "INDEX1",
                                        "INDEX2",
                                        "INDEX3",
                                        "INDEX4"
                                      ],
                                      "type": "string"
                                    },
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "index"
                                  ],
                                  "type": "object"
                                },
                                "productItemId": {
                                  "properties": {
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "productType": {
                                  "properties": {
                                    "level": {
                                      "enum": [
                                        "LEVEL1",
                                        "LEVEL2",
                                        "LEVEL3",
                                        "LEVEL4",
                                        "LEVEL5"
                                      ],
                                      "type": "string"
                                    },
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "level"
                                  ],
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "excluded": {
                              "description": "Leaf only. true excludes these products.",
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "dimension"
                          ],
                          "type": "object"
                        },
                        "minItems": 2,
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "name": {
                    "description": "Unique within the campaign.",
                    "maxLength": 128,
                    "minLength": 1,
                    "type": "string"
                  },
                  "path1": {
                    "maxLength": 15,
                    "type": "string"
                  },
                  "path2": {
                    "description": "Requires path1.",
                    "maxLength": 15,
                    "type": "string"
                  },
                  "status": {
                    "default": "PAUSED",
                    "enum": [
                      "ENABLED",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "validateOnly": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "finalUrls",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "validateOnly request accepted by Google. Nothing was created."
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "assetGroup": {
                      "properties": {
                        "campaignId": {
                          "type": "string"
                        },
                        "id": {
                          "type": "string"
                        },
                        "resourceName": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "campaignId",
                        "id",
                        "resourceName"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "assetGroup"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Asset group created."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a Performance Max asset group",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_google_asset_group@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "19b23d14159aef9a7165914385c1d8f56ad094691e5202138bc866b629c4954e"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_campaigns_campaignid_as_bb4817",
          "method": "POST",
          "path": "/apis/v1/ads/campaigns/{campaignId}/asset-groups"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_campaigns_campaignid_as_bb4817"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/asset-groups/{assetGroupId}": {
      "delete": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. validateOnly=true checks the request without acting and needs no confirmation. Permanently removes an asset group from a Performance Max campaign (this cannot be undone). Removes the asset group on Google (status REMOVED, not reversible). Pass validateOnly=true to validate without removing.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_campaigns_campaignid__5c211a",
        "parameters": [
          {
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "assetGroupId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "validateOnly",
            "required": false,
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "assetGroupId": {
                      "type": "string"
                    },
                    "removed": {
                      "type": "boolean"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Removed (or validated)."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove a Performance Max asset group",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_google_asset_group@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "b7f549cd4e76cac4b47a431deb3f7ec8eb148334e0f616b6d22c301ead4fcd19"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_campaigns_campaignid__5c211a",
          "method": "DELETE",
          "path": "/apis/v1/ads/campaigns/{campaignId}/asset-groups/{assetGroupId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_campaigns_campaignid__5c211a"
      },
      "get": {
        "description": "Ad Campaigns. Read only. Shows one Performance Max asset group with its linked assets, ad strength, status and product targeting tree. One asset group with its linked assets, ad strength, primary status and listing-group tree. Uses a 10-minute cache, served stale when Google quota is exhausted; any write below clears it.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_ass_5c211a",
        "parameters": [
          {
            "description": "Google Ads campaign id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Google asset group id.",
            "in": "path",
            "name": "assetGroupId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "assetGroup": {
                      "properties": {
                        "adStrength": {
                          "description": "Google ad strength, such as POOR, AVERAGE, GOOD or EXCELLENT.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "assets": {
                          "items": {
                            "properties": {
                              "fieldType": {
                                "description": "Google asset role, such as HEADLINE or LOGO.",
                                "type": "string"
                              },
                              "imageUrl": {
                                "format": "uri",
                                "type": "string"
                              },
                              "resourceName": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string"
                              },
                              "text": {
                                "type": "string"
                              },
                              "youtubeVideoId": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "fieldType",
                              "resourceName",
                              "status"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "campaignId": {
                          "type": "string"
                        },
                        "finalMobileUrls": {
                          "items": {
                            "format": "uri",
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "finalUrls": {
                          "items": {
                            "format": "uri",
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "id": {
                          "description": "Stable Google asset group id. Use it in the asset-group endpoints below.",
                          "type": "string"
                        },
                        "listingGroupFilters": {
                          "description": "The asset group's listing-group tree as flat nodes (retail campaigns). Empty when the group has none.",
                          "items": {
                            "properties": {
                              "dimension": {
                                "additionalProperties": true,
                                "description": "Google's case value for the node, such as { productBrand: { value: 'Acme' } }. A dimension with no value is the everything-else node. Null for the root.",
                                "type": [
                                  "object",
                                  "null"
                                ]
                              },
                              "id": {
                                "type": "string"
                              },
                              "listingSource": {
                                "type": "string"
                              },
                              "parentResourceName": {
                                "description": "Null for the root node.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "resourceName": {
                                "description": "customers/{customerId}/assetGroupListingGroupFilters/{assetGroupId}~{filterId}",
                                "type": "string"
                              },
                              "type": {
                                "enum": [
                                  "SUBDIVISION",
                                  "UNIT_INCLUDED",
                                  "UNIT_EXCLUDED"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "dimension",
                              "id",
                              "listingSource",
                              "parentResourceName",
                              "resourceName",
                              "type"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "name": {
                          "type": "string"
                        },
                        "path1": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "path2": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "primaryStatus": {
                          "description": "Why the group is or is not serving, such as ELIGIBLE, PAUSED or NOT_ELIGIBLE.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "primaryStatusReasons": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "resourceName": {
                          "description": "customers/{customerId}/assetGroups/{assetGroupId}",
                          "type": "string"
                        },
                        "status": {
                          "description": "Asset-group status on Google. Campaign status independently controls delivery.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "adStrength",
                        "assets",
                        "campaignId",
                        "finalMobileUrls",
                        "finalUrls",
                        "id",
                        "listingGroupFilters",
                        "name",
                        "path1",
                        "path2",
                        "primaryStatus",
                        "primaryStatusReasons",
                        "resourceName",
                        "status"
                      ],
                      "type": "object"
                    },
                    "cachedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "stale": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "assetGroup",
                    "cachedAt",
                    "stale"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The asset group."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get a Performance Max asset group",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_google_asset_group@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1191679471884f19ed133e4d08fd9fc67aa64f1b8c7eab9e95933e93f3f24ded"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_ass_5c211a",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/asset-groups/{assetGroupId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_ass_5c211a"
      },
      "patch": {
        "description": "Ad Campaigns. A pause needs ads:write. A change to active turns delivery on: it needs ads:spend and X-Aisa-Confirm: spend. validateOnly=true checks the request without acting and needs no confirmation. Changes a Performance Max asset group's name, status, final URLs or display paths. Change the name, status (ENABLED or PAUSED), final URLs or display paths. Only the fields sent are written; null on path1 or path2 clears it. Change assets with the /assets endpoint and product targeting with /listing-group-filters. validateOnly: true validates without writing.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_campaigns_campaignid_a_5c211a",
        "parameters": [
          {
            "description": "Google Ads campaign id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Google asset group id.",
            "in": "path",
            "name": "assetGroupId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "finalUrls": [
                  "https://example.com/sale"
                ],
                "status": "PAUSED"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "finalMobileUrls": {
                    "items": {
                      "format": "uri",
                      "type": "string"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  },
                  "finalUrls": {
                    "items": {
                      "format": "uri",
                      "type": "string"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  },
                  "name": {
                    "maxLength": 128,
                    "minLength": 1,
                    "type": "string"
                  },
                  "path1": {
                    "maxLength": 15,
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "path2": {
                    "maxLength": 15,
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "status": {
                    "enum": [
                      "ENABLED",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "validateOnly": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "assetGroupId": {
                      "type": "string"
                    },
                    "updated": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Updated (or validated)."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update a Performance Max asset group",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_google_asset_group@1",
          "required_scope": "ads:write",
          "scope_rule": "Pausing needs ads:write; turning delivery on needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "203128ac1089175908cbd103ffebf40732c31fb51b7b43310915a4653f4f6d1f"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_campaigns_campaignid_a_5c211a",
          "method": "PATCH",
          "path": "/apis/v1/ads/campaigns/{campaignId}/asset-groups/{assetGroupId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_campaigns_campaignid_a_5c211a"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/asset-groups/{assetGroupId}/assets": {
      "post": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. validateOnly=true checks the request without acting and needs no confirmation. Links new or existing assets to a Performance Max asset group and unlinks others in one change, keeping unlinked assets in the account library. Link existing assets or new content to the asset group, and unlink assets, in one atomic request. Links are applied before unlinks, so swapping the last asset of a role does not trip Google's per-role minimum.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_campaigns_campaignid_as_2291fd",
        "parameters": [
          {
            "description": "Google Ads campaign id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Google asset group id.",
            "in": "path",
            "name": "assetGroupId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "link": [
                  {
                    "fieldType": "HEADLINE",
                    "text": "Free shipping today"
                  }
                ],
                "unlink": [
                  {
                    "asset": "customers/9122445560/assets/419573236135",
                    "fieldType": "HEADLINE"
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "link": {
                    "items": {
                      "description": "Link one asset to the asset group. Send exactly one of asset (an existing asset), text, imageUrl or youtubeVideoId (new content, created in the same request).",
                      "properties": {
                        "asset": {
                          "description": "Existing asset id or resource name customers/{customerId}/assets/{assetId}. Must belong to the campaign's ad account.",
                          "type": "string"
                        },
                        "fieldType": {
                          "description": "Google AssetFieldType, such as HEADLINE, LONG_HEADLINE, DESCRIPTION, BUSINESS_NAME, MARKETING_IMAGE, SQUARE_MARKETING_IMAGE, PORTRAIT_MARKETING_IMAGE, LOGO, LANDSCAPE_LOGO or YOUTUBE_VIDEO.",
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Public http(s) image. Links as an image role or LOGO / LANDSCAPE_LOGO.",
                          "format": "uri",
                          "type": "string"
                        },
                        "text": {
                          "description": "Text assets link as HEADLINE, LONG_HEADLINE, DESCRIPTION or BUSINESS_NAME.",
                          "maxLength": 90,
                          "type": "string"
                        },
                        "youtubeVideoId": {
                          "description": "Links as YOUTUBE_VIDEO.",
                          "pattern": "^[A-Za-z0-9_-]{11}$",
                          "type": "string"
                        }
                      },
                      "required": [
                        "fieldType"
                      ],
                      "type": "object"
                    },
                    "maxItems": 100,
                    "type": "array"
                  },
                  "unlink": {
                    "items": {
                      "properties": {
                        "asset": {
                          "description": "Asset id or resource name, as returned in the asset group's assets.",
                          "type": "string"
                        },
                        "fieldType": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "asset",
                        "fieldType"
                      ],
                      "type": "object"
                    },
                    "maxItems": 100,
                    "type": "array"
                  },
                  "validateOnly": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "assetGroupId": {
                      "type": "string"
                    },
                    "linked": {
                      "type": "integer"
                    },
                    "unlinked": {
                      "type": "integer"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Links applied (or validated)."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Link or unlink asset group assets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.edit_google_asset_group_assets@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "7cdba9b1c2c0752d724a778b163ea0e22420f28acb2d7604fa4cdec54c27079e"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_campaigns_campaignid_as_2291fd",
          "method": "POST",
          "path": "/apis/v1/ads/campaigns/{campaignId}/asset-groups/{assetGroupId}/assets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_campaigns_campaignid_as_2291fd"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/asset-groups/{assetGroupId}/listing-group-filters": {
      "put": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. validateOnly=true checks the request without acting and needs no confirmation. Replaces the product targeting tree of a Performance Max retail asset group; only works on campaigns linked to Merchant Center. The current product (listing-group) tree is removed and the new one created in one atomic request. Read the current tree with GET on the asset group. Requires a campaign linked to Merchant Center. Other campaigns return 400 LISTING_SOURCE_NOT_ALLOWED from Google.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_ass_a1f9dd",
        "parameters": [
          {
            "description": "Google Ads campaign id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Google asset group id.",
            "in": "path",
            "name": "assetGroupId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "tree": {
                  "children": [
                    {
                      "dimension": {
                        "productBrand": {
                          "value": "example"
                        },
                        "productCategory": {
                          "level": "LEVEL1"
                        }
                      }
                    },
                    {
                      "dimension": {
                        "productBrand": {
                          "value": "example"
                        },
                        "productCategory": {
                          "level": "LEVEL1"
                        }
                      }
                    }
                  ]
                }
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "tree": {
                    "description": "The root of a Performance Max retail listing-group tree (listing source SHOPPING). No children targets all products. Requires a campaign linked to Merchant Center.",
                    "properties": {
                      "children": {
                        "items": {
                          "properties": {
                            "children": {
                              "description": "Makes the node a subdivision. Children share one dimension (and level or index) and include exactly one everything-else node.",
                              "items": {
                                "description": "Same shape as its parent.",
                                "type": "object"
                              },
                              "minItems": 2,
                              "type": "array"
                            },
                            "dimension": {
                              "description": "Exactly one key. Omit the value (for example { productBrand: {} }) for the everything-else node of that level.",
                              "properties": {
                                "productBrand": {
                                  "properties": {
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "productCategory": {
                                  "properties": {
                                    "categoryId": {
                                      "description": "Google product category id.",
                                      "type": "string"
                                    },
                                    "level": {
                                      "enum": [
                                        "LEVEL1",
                                        "LEVEL2",
                                        "LEVEL3",
                                        "LEVEL4",
                                        "LEVEL5"
                                      ],
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "level"
                                  ],
                                  "type": "object"
                                },
                                "productChannel": {
                                  "properties": {
                                    "channel": {
                                      "enum": [
                                        "ONLINE",
                                        "LOCAL"
                                      ],
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "productCondition": {
                                  "properties": {
                                    "condition": {
                                      "enum": [
                                        "NEW",
                                        "REFURBISHED",
                                        "USED"
                                      ],
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "productCustomAttribute": {
                                  "properties": {
                                    "index": {
                                      "enum": [
                                        "INDEX0",
                                        "INDEX1",
                                        "INDEX2",
                                        "INDEX3",
                                        "INDEX4"
                                      ],
                                      "type": "string"
                                    },
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "index"
                                  ],
                                  "type": "object"
                                },
                                "productItemId": {
                                  "properties": {
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "productType": {
                                  "properties": {
                                    "level": {
                                      "enum": [
                                        "LEVEL1",
                                        "LEVEL2",
                                        "LEVEL3",
                                        "LEVEL4",
                                        "LEVEL5"
                                      ],
                                      "type": "string"
                                    },
                                    "value": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "level"
                                  ],
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "excluded": {
                              "description": "Leaf only. true excludes these products.",
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "dimension"
                          ],
                          "type": "object"
                        },
                        "minItems": 2,
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "validateOnly": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "tree"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "assetGroupId": {
                      "type": "string"
                    },
                    "created": {
                      "description": "Nodes in the new tree.",
                      "type": "integer"
                    },
                    "removed": {
                      "description": "Nodes removed from the previous tree.",
                      "type": "integer"
                    },
                    "validateOnly": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Tree replaced (or validated)."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Replace an asset group's listing-group tree",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.replace_google_listing_group_filters@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "c1231261946247fe2f77ac02c59f135d1f1c3f61943d4ef3b27bb8914fee48a2"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_ass_a1f9dd",
          "method": "PUT",
          "path": "/apis/v1/ads/campaigns/{campaignId}/asset-groups/{assetGroupId}/listing-group-filters"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_campaigns_campaignid_ass_a1f9dd"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/assets": {
      "delete": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Detaches assets from a Google campaign without deleting them, so they stay in the account and on anything else they are attached to. Google assets cannot be deleted. Other attachments remain. assetResourceNames is retained for compatibility. Fields go in the query string. A JSON body with the same fields is also accepted and, when sent, the query string is ignored.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_campaigns_campaignid_assets",
        "parameters": [
          {
            "description": "Numeric Google platform id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Asset resource names, retained for compatibility. Repeat the parameter or pass a comma-separated list.",
            "in": "query",
            "name": "assetResourceNames",
            "required": true,
            "schema": {
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "type": "array"
            }
          },
          {
            "description": "campaign_asset resource names to remove, e.g. customers/1234567890/campaignAssets/456~123~CALLOUT. Repeat the parameter or pass a comma-separated list.",
            "in": "query",
            "name": "campaignAssetResourceNames",
            "required": true,
            "schema": {
              "items": {
                "type": "string"
              },
              "minItems": 1,
              "type": "array"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "removed": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove campaign assets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_campaign_assets@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "5f2b16d611496d16b8275ca0d0efe49f8ddc2ee502617c2589c690bfdf1675f9"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_campaigns_campaignid_assets",
          "method": "DELETE",
          "path": "/apis/v1/ads/campaigns/{campaignId}/assets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_campaigns_campaignid_assets"
      },
      "get": {
        "description": "Ad Campaigns. Read only. Lists the sitelinks, callouts and other assets attached directly to a Google campaign. Fresh reads are cached for 10 minutes; exhausted quota may return the last successful read with stale=true. Inherited assets are not included.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_assets",
        "parameters": [
          {
            "description": "Numeric Google platform id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "description": "Alias of adAccountId, kept for existing callers",
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "Time of the cached Google read. Null when no cache was used.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "callouts": {
                      "items": {
                        "properties": {
                          "assetResourceName": {
                            "type": "string"
                          },
                          "calloutText": {
                            "type": "string"
                          },
                          "campaignAssetResourceName": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "campaignId": {
                      "type": "string"
                    },
                    "images": {
                      "items": {
                        "properties": {
                          "assetResourceName": {
                            "type": "string"
                          },
                          "campaignAssetResourceName": {
                            "type": "string"
                          },
                          "height": {
                            "type": "integer"
                          },
                          "imageUrl": {
                            "description": "Google-hosted copy of the image.",
                            "format": "uri",
                            "type": "string"
                          },
                          "width": {
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "sitelinks": {
                      "items": {
                        "properties": {
                          "assetResourceName": {
                            "type": "string"
                          },
                          "campaignAssetResourceName": {
                            "type": "string"
                          },
                          "description1": {
                            "type": "string"
                          },
                          "description2": {
                            "type": "string"
                          },
                          "linkUrl": {
                            "format": "uri",
                            "type": "string"
                          },
                          "text": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when exhausted quota required returning the last successful read.",
                      "type": "boolean"
                    },
                    "structuredSnippets": {
                      "items": {
                        "properties": {
                          "assetResourceName": {
                            "type": "string"
                          },
                          "campaignAssetResourceName": {
                            "type": "string"
                          },
                          "header": {
                            "type": "string"
                          },
                          "values": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List campaign assets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_campaign_assets@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "3521ce95d732ab533e87a5d24726015e986cca2c2583e134b2e0cd8fc9c02311"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_assets",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/assets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_assets"
      },
      "post": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Adds sitelinks, callouts, structured snippets and images to a Google campaign in one step. Creates and attaches sitelinks, callouts, structured snippets and image assets in one Google mutation. Google shows images only on accounts it deems eligible (account age, policy history, vertical).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_campaigns_campaignid_assets",
        "parameters": [
          {
            "description": "Numeric Google platform id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "callouts": [
                  "Fast setup"
                ],
                "connectionId": "adc_7f3k2m9q",
                "sitelinks": [
                  {
                    "linkUrl": "https://example.com/landing",
                    "text": "Pricing"
                  },
                  {
                    "linkUrl": "https://example.com/landing",
                    "text": "Documentation"
                  }
                ],
                "structuredSnippets": [
                  {
                    "header": "Types",
                    "values": [
                      "Scheduling",
                      "Analytics",
                      "Messaging"
                    ]
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "description": "Provide at least one of sitelinks, callouts, structuredSnippets or images. Sitelink description1 and description2 must be supplied together.",
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "callouts": {
                    "items": {
                      "maxLength": 25,
                      "minLength": 1,
                      "type": "string"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "images": {
                    "description": "Public image URLs, uploaded to Google as image assets. Landscape 1.91:1 (min 600x314) or square 1:1 (min 300x300), up to 5 MB each.",
                    "items": {
                      "format": "uri",
                      "type": "string"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  },
                  "sitelinks": {
                    "items": {
                      "properties": {
                        "description1": {
                          "maxLength": 35,
                          "minLength": 1,
                          "type": "string"
                        },
                        "description2": {
                          "maxLength": 35,
                          "minLength": 1,
                          "type": "string"
                        },
                        "linkUrl": {
                          "format": "uri",
                          "type": "string"
                        },
                        "text": {
                          "maxLength": 25,
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "linkUrl",
                        "text"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 2,
                    "type": "array"
                  },
                  "structuredSnippets": {
                    "items": {
                      "properties": {
                        "header": {
                          "enum": [
                            "Amenities",
                            "Brands",
                            "Courses",
                            "Degree programs",
                            "Destinations",
                            "Featured hotels",
                            "Insurance coverage",
                            "Models",
                            "Neighborhoods",
                            "Service catalog",
                            "Shows",
                            "Styles",
                            "Types"
                          ],
                          "type": "string"
                        },
                        "values": {
                          "items": {
                            "maxLength": 25,
                            "minLength": 1,
                            "type": "string"
                          },
                          "maxItems": 10,
                          "minItems": 3,
                          "type": "array"
                        }
                      },
                      "required": [
                        "header",
                        "values"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "calloutAssetResourceNames": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "campaignId": {
                      "type": "string"
                    },
                    "imageAssetResourceNames": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "sitelinkAssetResourceNames": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "structuredSnippetAssetResourceNames": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets created and attached."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Attach campaign assets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.attach_campaign_assets@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "53dfb5a8c2a7eb39b1d4d41cb1133675c75c8a14b5fb2e3d7f1c5426dbc17c05"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_campaigns_campaignid_assets",
          "method": "POST",
          "path": "/apis/v1/ads/campaigns/{campaignId}/assets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_campaigns_campaignid_assets"
      },
      "put": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Edits a Google campaign's existing assets, such as sitelinks or callouts, in place; the change applies everywhere that asset is used. Send updates with assetResourceName and the fields to change. An asset is shared: changes affect every attachment using it. Omitted fields stay unchanged. The operation consumes the Google operations budget and invalidates affected cached lists.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_assets",
        "parameters": [
          {
            "description": "Numeric Google platform id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "updates": [
                  {
                    "assetResourceName": "customers/1234567890/assets/123",
                    "calloutAsset": {
                      "calloutText": "Simple integration"
                    }
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "updates": {
                    "items": {
                      "description": "Supply fields for exactly one asset type per update. finalUrls may accompany sitelinkAsset. Shared asset edits affect every attachment using the asset.",
                      "properties": {
                        "assetResourceName": {
                          "description": "Asset resource name returned by a list operation. Must belong to the selected customer.",
                          "pattern": "^customers/\\d+/assets/\\d+$",
                          "type": "string"
                        },
                        "calloutAsset": {
                          "properties": {
                            "calloutText": {
                              "maxLength": 25,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "calloutText"
                          ],
                          "type": "object"
                        },
                        "finalUrls": {
                          "items": {
                            "format": "uri",
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "sitelinkAsset": {
                          "properties": {
                            "description1": {
                              "maxLength": 35,
                              "type": "string"
                            },
                            "description2": {
                              "maxLength": 35,
                              "type": "string"
                            },
                            "linkText": {
                              "maxLength": 25,
                              "minLength": 1,
                              "type": "string"
                            },
                            "linkUrl": {
                              "description": "Alias for finalUrls with one URL. Do not supply both.",
                              "format": "uri",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "structuredSnippetAsset": {
                          "properties": {
                            "header": {
                              "enum": [
                                "Amenities",
                                "Brands",
                                "Courses",
                                "Degree programs",
                                "Destinations",
                                "Featured hotels",
                                "Insurance coverage",
                                "Models",
                                "Neighborhoods",
                                "Service catalog",
                                "Shows",
                                "Styles",
                                "Types"
                              ],
                              "type": "string"
                            },
                            "values": {
                              "items": {
                                "maxLength": 25,
                                "minLength": 1,
                                "type": "string"
                              },
                              "maxItems": 10,
                              "minItems": 3,
                              "type": "array"
                            }
                          },
                          "required": [
                            "header",
                            "values"
                          ],
                          "type": "object"
                        }
                      },
                      "required": [
                        "assetResourceName"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "updates"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "updated": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assets returned."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update campaign assets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_campaign_assets@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "eda3ff6e685584ac928ad44e8412815bcf5cd6538cf2100e48f76c253c601244"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_assets",
          "method": "PUT",
          "path": "/apis/v1/ads/campaigns/{campaignId}/assets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_campaigns_campaignid_assets"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/bidding": {
      "get": {
        "description": "Ad Campaigns. Read only. Shows a Google campaign's current bidding strategy and targets, ready to prefill an edit. Reads the campaign's bidding strategy on Google, cached for the quota window, for pre-filling the bid strategy block before a PUT to /apis/v1/ads/campaigns/{campaignId}. Google Ads only. `platform` is required and rejected when it is anything else, since a `campaignId` is not globally unique.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_bidding",
        "parameters": [
          {
            "description": "Numeric Google platform campaign id.",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required: campaign IDs are not globally unique. Only \"google\" is supported today.",
            "in": "query",
            "name": "platform",
            "required": true,
            "schema": {
              "enum": [
                "google"
              ],
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple Google Ads accounts; optional (and inferred) when it has only one.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "description": "A Google campaign's current bidding, mapped onto the same triplet PUT /apis/v1/ads/campaigns/{campaignId} accepts.",
                  "properties": {
                    "bidSpec": {
                      "description": "Null when the campaign is on a strategy PUT does not model (Manual CPC, Target Impression Share, ...); show biddingStrategyType instead in that case.",
                      "properties": {
                        "bidAmount": {
                          "description": "Whole currency units. Present for COST_CAP and LOWEST_COST_WITH_BID_CAP, and omitted when the campaign is on a bare TARGET_SPEND with no CPC ceiling set.",
                          "type": "number"
                        },
                        "bidStrategy": {
                          "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                          "enum": [
                            "LOWEST_COST_WITHOUT_CAP",
                            "LOWEST_COST_WITH_BID_CAP",
                            "COST_CAP",
                            "LOWEST_COST_WITH_MIN_ROAS"
                          ],
                          "type": "string"
                        },
                        "portfolioBidStrategyId": {
                          "description": "Present alone (bidStrategy omitted) when the campaign is on a portfolio strategy; see portfolio.",
                          "type": "string"
                        },
                        "roasAverageFloor": {
                          "description": "Decimal ROAS multiplier (2.0 = 2.0x). Present for LOWEST_COST_WITH_MIN_ROAS.",
                          "type": "number"
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "biddingStrategyType": {
                      "description": "Google's raw enum: MAXIMIZE_CONVERSIONS, TARGET_CPA, MAXIMIZE_CONVERSION_VALUE, TARGET_ROAS, TARGET_SPEND, MANUAL_CPC, TARGET_IMPRESSION_SHARE, or another Google adds later.",
                      "type": "string"
                    },
                    "cachedAt": {
                      "description": "When this data was fetched from Google. Null when it was never served from cache.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "campaignId": {
                      "type": "string"
                    },
                    "channel": {
                      "description": "campaign.advertising_channel_type. COST_CAP's underlying Google field differs by channel; see bidStrategy on PUT.",
                      "enum": [
                        "SEARCH",
                        "DISPLAY"
                      ],
                      "type": "string"
                    },
                    "portfolio": {
                      "description": "Set only when the campaign is on a portfolio bid strategy (campaign.bidding_strategy); null otherwise.",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "stale": {
                      "description": "True when Google's daily API quota was exhausted and this is the last successful fetch, not a live read.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign bidding"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Read a campaign's current bidding",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_campaign_bidding@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "fd5a19ca6cb0196a7ca214d1099c70c90b5175b64d5791be0027ea0b7f85a7e2"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_bidding",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/bidding"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_bidding"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/conversion-goals": {
      "get": {
        "description": "Ad Campaigns. Read only. Shows which conversion goals a Google campaign bids on, and whether it follows the account defaults or uses its own or a custom goal.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_con_6ea0b0",
        "parameters": [
          {
            "description": "Google campaign id",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "campaignId": {
                      "type": "string"
                    },
                    "customConversionGoalId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "goalConfigLevel": {
                      "enum": [
                        "CUSTOMER",
                        "CAMPAIGN",
                        "UNSPECIFIED",
                        "UNKNOWN"
                      ],
                      "type": "string"
                    },
                    "goals": {
                      "items": {
                        "properties": {
                          "biddable": {
                            "type": "boolean"
                          },
                          "category": {
                            "type": "string"
                          },
                          "origin": {
                            "type": "string"
                          },
                          "resourceName": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign conversion goals"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get campaign conversion goals",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_campaign_conversion_goals@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "20d847e1d059fa90ee107f6138c812d4a8da51dadc86d890912278260e633619"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_con_6ea0b0",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/conversion-goals"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_con_6ea0b0"
      },
      "patch": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Changes which conversions a Google campaign bids on, switching between account-default goals, its own goals or a custom goal. In one mutate, it can: set `biddable` on campaign goals switch `goalConfigLevel` point the campaign at a custom conversion goal `customConversionGoalId: null` clears it.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_campaigns_campaignid_c_6ea0b0",
        "parameters": [
          {
            "description": "Google campaign id",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "customConversionGoalId": "1234567890",
                "goalConfigLevel": "CUSTOMER"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customConversionGoalId": {
                    "description": "Custom goal to bid on, or null to clear",
                    "pattern": "^\\d+$",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "goalConfigLevel": {
                    "enum": [
                      "CUSTOMER",
                      "CAMPAIGN"
                    ],
                    "type": "string"
                  },
                  "goals": {
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "biddable": {
                          "type": "boolean"
                        },
                        "category": {
                          "description": "Google ConversionActionCategory, e.g. PURCHASE, SIGNUP, SUBMIT_LEAD_FORM",
                          "pattern": "^[A-Z][A-Z0-9_]*$",
                          "type": "string"
                        },
                        "origin": {
                          "description": "Google ConversionOrigin, e.g. WEBSITE, APP, CALL_FROM_ADS, STORE, GOOGLE_HOSTED",
                          "pattern": "^[A-Z][A-Z0-9_]*$",
                          "type": "string"
                        }
                      },
                      "required": [
                        "biddable",
                        "category",
                        "origin"
                      ],
                      "type": "object"
                    },
                    "maxItems": 100,
                    "type": "array"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "campaignId": {
                      "type": "string"
                    },
                    "customConversionGoalId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "goalConfigLevel": {
                      "enum": [
                        "CUSTOMER",
                        "CAMPAIGN",
                        "UNSPECIFIED",
                        "UNKNOWN"
                      ],
                      "type": "string"
                    },
                    "goals": {
                      "items": {
                        "properties": {
                          "biddable": {
                            "type": "boolean"
                          },
                          "category": {
                            "type": "string"
                          },
                          "origin": {
                            "type": "string"
                          },
                          "resourceName": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign goals updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update campaign conversion goals",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_campaign_conversion_goals@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "5fb34b9214e9761a50dd3fa2fdc64cffd48c2ed3b5aecc902e33a9a37102a9c7"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_campaigns_campaignid_c_6ea0b0",
          "method": "PATCH",
          "path": "/apis/v1/ads/campaigns/{campaignId}/conversion-goals"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_campaigns_campaignid_c_6ea0b0"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/duplicate": {
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Copies a campaign, with its budget; an active copy starts spending. Copies a campaign with its ad sets, ads, creatives and targeting, created paused so you can review it before launch. Ad sets, ads, creatives, and targeting are copied by default (`deepCopy: true`). The copy is created paused so callers can review before launching. ### Per-platform implementation Meta copies one level at a time with Meta's `/copies` endpoint. See below.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_campaigns_campaignid_duplicate",
        "parameters": [
          {
            "description": "Source platform campaign ID",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "deepCopy": true,
                "endTime": "2026-12-01T09:00:00Z"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "deepCopy": {
                    "default": true,
                    "description": "Copy child ad sets + ads + creatives + targeting",
                    "type": "boolean"
                  },
                  "endTime": {
                    "description": "Reschedule the copied hierarchy's end, read like `startTime`; a date-only end runs to 23:59:59 local. Defaults to the source's end.",
                    "format": "date-time",
                    "type": "string"
                  },
                  "platform": {
                    "description": "Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "meta"
                    ],
                    "type": "string"
                  },
                  "renamePrefix": {
                    "description": "Text prepended to each renamed object's name.",
                    "type": "string"
                  },
                  "renameStrategy": {
                    "description": "Meta's native `rename_strategy` values: `DEEP_RENAME`: renames the copied campaign and every copied child (ad sets, ads) with `renamePrefix` / `renameSuffix`.",
                    "enum": [
                      "DEEP_RENAME",
                      "ONLY_TOP_LEVEL_RENAME",
                      "NO_RENAME"
                    ],
                    "type": "string"
                  },
                  "renameSuffix": {
                    "description": "Text appended to each renamed object's name. On LinkedIn an omitted suffix defaults to ` (Copy)`.",
                    "type": "string"
                  },
                  "startTime": {
                    "description": "Reschedule the copied hierarchy's start (ISO 8601). TikTok defaults to a start a few minutes after the copy.",
                    "format": "date-time",
                    "type": "string"
                  },
                  "statusOption": {
                    "default": "PAUSED",
                    "description": "ACTIVE = launch the clone immediately (spends the moment LinkedIn approves it). PAUSED = clone stays DRAFT, safe default. INHERITED_FROM_SOURCE = mirror each entity's source status per-entity.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED",
                      "INHERITED_FROM_SOURCE"
                    ],
                    "type": "string"
                  },
                  "syncAfter": {
                    "default": true,
                    "description": "Trigger ads discovery on the owning account after the copy succeeds",
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adIdMap": {
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Meta only: source ad ID to copied ad ID, across every copied ad set. Empty when `deepCopy` is false.",
                      "type": "object"
                    },
                    "adSetIdMap": {
                      "additionalProperties": {
                        "type": "string"
                      },
                      "description": "Meta only: source ad set ID to copied ad set ID. Empty when `deepCopy` is false.",
                      "type": "object"
                    },
                    "copiedCampaignId": {
                      "description": "Platform ID of the new campaign",
                      "type": "string"
                    },
                    "discovery": {
                      "enum": [
                        "triggered",
                        "skipped",
                        "failed"
                      ],
                      "type": "string"
                    },
                    "raw": {
                      "description": "Platform-native response from the copy (TikTok and LinkedIn). Absent on Meta, which returns `adSetIdMap` and `adIdMap` instead.",
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign duplicated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Duplicate a campaign",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.duplicate_ad_campaign@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e36e34a956b235a625f07f6df2e10bf3df03ee799d5c52117d69cb70717fcabf"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_campaigns_campaignid_duplicate",
          "method": "POST",
          "path": "/apis/v1/ads/campaigns/{campaignId}/duplicate"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_campaigns_campaignid_duplicate"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/negative-keyword-lists": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists the shared negative keyword lists attached to a Google campaign, separate from its own campaign-level negatives. Google Ads shared negative keyword lists (shared_set type NEGATIVE_KEYWORDS). Reads are cached for 10 minutes; quota exhaustion may return the last successful result for up to 7 days with stale=true. Customer selection is limited to this connection and its account scope.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_24428f",
        "parameters": [
          {
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "description": "Google campaign id.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "description": "Optional courtesy field. The resolved account or campaign determines support; other platforms return 501.",
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "meta",
                "x"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "Last successful fetch time, or null without cache storage.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "description": "Resolved Google Ads customer id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "lists": {
                      "items": {
                        "properties": {
                          "id": {
                            "description": "Google shared set id.",
                            "pattern": "^\\d+$",
                            "type": "string"
                          },
                          "memberCount": {
                            "description": "Number of keywords in the list.",
                            "type": "integer"
                          },
                          "name": {
                            "description": "List name.",
                            "type": "string"
                          },
                          "referenceCount": {
                            "description": "Number of resources referencing the list.",
                            "type": "integer"
                          },
                          "resourceName": {
                            "description": "Google shared set resource name.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when quota exhaustion caused the last successful cached result to be served.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Successful response."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List campaign negative lists",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_campaign_negative_keyword_lists@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a7674e4993e810ea92bc62ea5ab1125ac6d55cce89e7076a51c34a4da807e02f"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_24428f",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/negative-keyword-lists"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_24428f"
      },
      "put": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Sets exactly which shared negative keyword lists apply to a Google campaign, or detaches them all, without changing the lists themselves. Send listIds=[] to detach all negative keyword lists. Only campaign_shared_set links are changed; the lists and their keywords are preserved. Every list must belong to the campaign customer and have type NEGATIVE_KEYWORDS.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_24428f",
        "parameters": [
          {
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "description": "Google campaign id.",
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "listIds": [
                  "1234567890"
                ],
                "platform": "google"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "listIds": {
                    "items": {
                      "description": "Shared negative keyword list id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "maxItems": 20,
                    "type": "array"
                  },
                  "platform": {
                    "description": "Optional courtesy field. The resolved account or campaign determines support; other platforms return 501. Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "listIds"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "created": {
                      "description": "New criteria or campaign links created.",
                      "type": "integer"
                    },
                    "customerId": {
                      "description": "Resolved Google Ads customer id.",
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "removed": {
                      "description": "Existing criteria or campaign links removed.",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Successful response."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Replace campaign negative lists",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.replace_campaign_negative_keyword_lists@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "39a25cca9b680ac208bdd02cab647e2377d1641295ad875d51df86ef41ac2f39"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_24428f",
          "method": "PUT",
          "path": "/apis/v1/ads/campaigns/{campaignId}/negative-keyword-lists"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_24428f"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/negative-keywords": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists the negative keywords set on a whole Google campaign, separate from ad group negatives. It returns the campaign-level negative keywords (`campaign_criterion.negative`), distinct from the ad-group-level negatives under `GET /apis/v1/ads/keywords`. ### Caching and quota\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_d9291b",
        "parameters": [
          {
            "description": "Platform campaign ID",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Optional and NOT authoritative: the resolved campaign's own platform decides 200 vs 501, never this hint.",
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "meta",
                "x"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "When this list was fetched from Google. Null when it was never served from cache.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "keywords": {
                      "items": {
                        "properties": {
                          "criterionId": {
                            "type": "string"
                          },
                          "matchType": {
                            "enum": [
                              "exact",
                              "phrase",
                              "broad"
                            ],
                            "type": "string"
                          },
                          "text": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when Google's daily API quota was exhausted and this is the last successful fetch, not a live read.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign-level negative keywords"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List campaign-level negative keywords",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_campaign_negative_keywords@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "5472109a64dddb3f899fadf7557551ede1d666744535519b8303b9de1f1fbce9"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_d9291b",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/negative-keywords"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_d9291b"
      },
      "put": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Replaces a Google campaign's full list of campaign-level negative keywords, or clears it. Replaces the FULL set of campaign-level negative keywords (C.270): the desired list is diffed against what Google already has, and the difference is applied as one `create`/`remove` mutate. Send an empty array to clear every campaign negative.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_d9291b",
        "parameters": [
          {
            "description": "Platform campaign ID",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "keywords": [
                  "example"
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "keywords": {
                    "items": {
                      "description": "A Google Search keyword: a bare string (BROAD match), or an object naming the match type.",
                      "oneOf": [
                        {
                          "description": "Keyword text; defaults to BROAD match",
                          "maxLength": 80,
                          "minLength": 1,
                          "type": "string"
                        },
                        {
                          "properties": {
                            "matchType": {
                              "description": "Defaults to broad. Accepted in any case (EXACT, Exact) and stored lowercase.",
                              "enum": [
                                "exact",
                                "phrase",
                                "broad"
                              ],
                              "type": "string"
                            },
                            "text": {
                              "maxLength": 80,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "maxItems": 1000,
                    "type": "array"
                  },
                  "platform": {
                    "description": "Optional and NOT authoritative: the resolved campaign's own platform decides 200 vs 501, never this hint. Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "keywords"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "created": {
                      "description": "Negative criteria newly created on Google",
                      "type": "integer"
                    },
                    "keywords": {
                      "description": "The full negative-keyword set after the replace",
                      "items": {
                        "properties": {
                          "criterionId": {
                            "type": "string"
                          },
                          "matchType": {
                            "enum": [
                              "exact",
                              "phrase",
                              "broad"
                            ],
                            "type": "string"
                          },
                          "text": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "removed": {
                      "description": "Negative criteria removed from Google",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign-level negative keywords replaced"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Replace campaign-level negative keywords",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.replace_campaign_negative_keywords@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "d3bf876150b04a0b2f41bf7de09ed70cc73a595fc2f53d6f131132a187a76e09"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_d9291b",
          "method": "PUT",
          "path": "/apis/v1/ads/campaigns/{campaignId}/negative-keywords"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_campaigns_campaignid_neg_d9291b"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/status": {
      "put": {
        "description": "Ad Campaigns. A pause needs ads:write. A change to active turns delivery on: it needs ads:spend and X-Aisa-Confirm: spend. Pauses or resumes a campaign, leaving the on/off switches of its ad sets and ads as they are. It writes the campaign's own on/off switch and nothing else, on every platform: Meta, TikTok, Google, LinkedIn campaign group, Pinterest, X, ChatGPT (OpenAI). Its ad sets and ads keep their own switches: Pausing stops their delivery through the campaign.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_status",
        "parameters": [
          {
            "description": "Platform campaign ID",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "status": "active"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "platform": {
                    "description": "Filled from the connection when omitted.",
                    "enum": [
                      "facebook",
                      "instagram",
                      "tiktok",
                      "linkedin",
                      "pinterest",
                      "google",
                      "twitter",
                      "openai",
                      "reddit",
                      "microsoft",
                      "meta",
                      "x"
                    ],
                    "type": "string"
                  },
                  "status": {
                    "enum": [
                      "active",
                      "paused"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "status"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "platformCampaignStatus": {
                      "description": "The campaign's own switch as read back from the platform, in the raw platform vocabulary: Meta effective_status, TikTok ENABLE / DISABLE, Google ENABLED / PAUSED, ChatGPT (OpenAI) status, Reddit configured_status.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "skipped": {
                      "description": "1 when a live read showed the campaign already in the requested state, so nothing was written.",
                      "enum": [
                        0,
                        1
                      ],
                      "type": "integer"
                    },
                    "skippedReasons": {
                      "description": "Why the write was skipped, for example \"Campaign already switched off\".",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "status": {
                      "description": "The campaign's delivery status derived from its switch as read back (`paused` when the switch is off). Echoes the request when the platform could not be read.",
                      "enum": [
                        "active",
                        "paused"
                      ],
                      "type": "string"
                    },
                    "statusReadAt": {
                      "description": "When the switch was read back. Null when it could not be read.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "updated": {
                      "description": "1 when the campaign's switch was written.",
                      "enum": [
                        0,
                        1
                      ],
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Campaign status updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Pause or resume a campaign",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_campaign_status@1",
          "required_scope": "ads:write",
          "scope_rule": "Pausing needs ads:write; turning delivery on needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "8e2e43896de9822ac408bc505c614974d32b1e34b0fe06c8f27a41dcf81f61f1"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_status",
          "method": "PUT",
          "path": "/apis/v1/ads/campaigns/{campaignId}/status"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_campaigns_campaignid_status"
      }
    },
    "/apis/v1/ads/campaigns/{campaignId}/targeting": {
      "get": {
        "description": "Ad Campaigns. Read only. Shows a Google campaign's device, location, excluded location and language targeting so you can build an editor for it. Google Ads compliance requires geo, language, budget, and bidding targeting set at creation to stay editable afterwards. This reads the campaign state so an integrator can build an editor around it.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_targeting",
        "parameters": [
          {
            "description": "Google platform campaign ID",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Disambiguates when the same campaignId string exists on more than one connected platform.",
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "google"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "When this targeting was fetched from Google. Null when it was never served from cache.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "devices": {
                      "items": {
                        "properties": {
                          "bidModifier": {
                            "description": "Google's bid adjustment for this device: null when it has none, 0 when the device is switched off, otherwise 0.1 to 10.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "device": {
                            "enum": [
                              "MOBILE",
                              "DESKTOP",
                              "TABLET",
                              "CONNECTED_TV"
                            ],
                            "type": "string"
                          },
                          "included": {
                            "type": "boolean"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "excludedLocations": {
                      "description": "The negative (excluded) location criteria, same item shape as `locations` with `negative: true`.",
                      "items": {
                        "properties": {
                          "canonicalName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "countryCode": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "geoTargetId": {
                            "description": "Numeric id from Google's geoTargetConstants/{id}.",
                            "type": "string"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "negative": {
                            "description": "Always true here.",
                            "type": "boolean"
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "excludedLocationsEditable": {
                      "description": "Whether PUT accepts `excludedLocations` for this campaign. False on Demand Gen, which returns 400 for any exclusion.",
                      "type": "boolean"
                    },
                    "languages": {
                      "items": {
                        "properties": {
                          "code": {
                            "description": "Google's language code (ISO 639-1, plus variants such as `zh_CN`).",
                            "type": "string"
                          },
                          "id": {
                            "description": "Google's languageConstants/{id} numeric id.",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "locationTargetingType": {
                      "description": "Who the location targeting reaches, see GoogleLocationTargetingType. Null when Google reports a legacy value (SEARCH_INTEREST) this API does not set.",
                      "enum": [
                        "presence",
                        "presence_or_interest",
                        null
                      ],
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "locations": {
                      "items": {
                        "properties": {
                          "canonicalName": {
                            "description": "Google's geo_target_constant.canonical_name, e.g. \"California, United States\"; null when the id could not be resolved.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "countryCode": {
                            "description": "Google's geo_target_constant.country_code, an ISO 3166-1 alpha-2 code; null when the id could not be resolved.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "geoTargetId": {
                            "description": "Numeric id from Google's geoTargetConstants/{id}.",
                            "type": "string"
                          },
                          "name": {
                            "description": "Google's geo_target_constant.name, e.g. \"United States\"; null when the id could not be resolved.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "negative": {
                            "description": "true = excluded location.",
                            "type": "boolean"
                          },
                          "type": {
                            "description": "Google's geo_target_constant.target_type, e.g. \"Country\", \"Region\", \"City\"; null when the id could not be resolved.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "description": "True when Google's daily API quota was exhausted and this is the last successful fetch, not a live read.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Current campaign targeting"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Read a Google campaign's device, location, excluded location, and language targeting",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_campaign_targeting@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "07db5326101c16abb43992c832eb7b937c606753135ab4a9bd8a695e2113ca82"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_campaigns_campaignid_targeting",
          "method": "GET",
          "path": "/apis/v1/ads/campaigns/{campaignId}/targeting"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_campaigns_campaignid_targeting"
      },
      "put": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Changes who a campaign can reach, which changes its delivery and spend. Changes a Google campaign's device, location, excluded location or language targeting after it was created. Google only; every other platform returns 501. Google Ads compliance row M.10: geo and language targeting set at creation must stay editable afterwards. Send at least one of `devices`, `locations`, `excludedLocations`, `languages`, `locationTargetingType`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_targeting",
        "parameters": [
          {
            "description": "Google platform campaign ID",
            "in": "path",
            "name": "campaignId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "targeting": {
                  "devices": [
                    "MOBILE"
                  ],
                  "excludedLocations": [
                    "example"
                  ]
                }
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "platform": {
                    "description": "Filled from the connection when omitted.",
                    "enum": [
                      "google"
                    ],
                    "type": "string"
                  },
                  "targeting": {
                    "properties": {
                      "devices": {
                        "description": "Devices to include. Devices not listed become excluded (negative) criteria, same contract as the existing devices-only edit.",
                        "items": {
                          "oneOf": [
                            {
                              "enum": [
                                "MOBILE",
                                "DESKTOP",
                                "TABLET",
                                "CONNECTED_TV"
                              ],
                              "type": "string"
                            },
                            {
                              "properties": {
                                "bidModifier": {
                                  "description": "Bid modifier for this device; devices without one use the campaign's base bid.",
                                  "type": "number"
                                },
                                "device": {
                                  "enum": [
                                    "MOBILE",
                                    "DESKTOP",
                                    "TABLET",
                                    "CONNECTED_TV"
                                  ],
                                  "type": "string"
                                }
                              },
                              "required": [
                                "bidModifier",
                                "device"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Locations the campaign never serves in, as a bare country-code array or the nested countries/regions/cities/zips/metros shape. Replaces the excluded set; [] removes every exclusion.",
                        "oneOf": [
                          {
                            "items": {
                              "description": "ISO 3166-1 alpha-2 country code.",
                              "type": "string"
                            },
                            "type": "array"
                          },
                          {
                            "additionalProperties": false,
                            "properties": {
                              "cities": {
                                "items": {
                                  "oneOf": [
                                    {
                                      "description": "The geo target constant id alone.",
                                      "type": "string"
                                    },
                                    {
                                      "properties": {
                                        "key": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "key"
                                      ],
                                      "type": "object"
                                    }
                                  ]
                                },
                                "type": "array"
                              },
                              "countries": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "metros": {
                                "items": {
                                  "oneOf": [
                                    {
                                      "description": "The geo target constant id alone.",
                                      "type": "string"
                                    },
                                    {
                                      "properties": {
                                        "key": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "key"
                                      ],
                                      "type": "object"
                                    }
                                  ]
                                },
                                "type": "array"
                              },
                              "regions": {
                                "items": {
                                  "oneOf": [
                                    {
                                      "description": "The geo target constant id alone.",
                                      "type": "string"
                                    },
                                    {
                                      "properties": {
                                        "key": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "key"
                                      ],
                                      "type": "object"
                                    }
                                  ]
                                },
                                "type": "array"
                              },
                              "zips": {
                                "items": {
                                  "oneOf": [
                                    {
                                      "description": "The geo target constant id alone.",
                                      "type": "string"
                                    },
                                    {
                                      "properties": {
                                        "key": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "key"
                                      ],
                                      "type": "object"
                                    }
                                  ]
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          }
                        ]
                      },
                      "languages": {
                        "description": "Google's language codes (ISO 639-1, plus variants such as `zh_CN`), e.g. [\"en\", \"de\"].",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "locationTargetingType": {
                        "description": "Google only. Who a campaign's location targeting reaches (Google's `campaign.geo_target_type_setting.positive_geo_target_type`). `presence`: people in, or regularly in, the targeted locations.",
                        "enum": [
                          "presence",
                          "presence_or_interest"
                        ],
                        "type": "string"
                      },
                      "locations": {
                        "description": "Bare country-code array, or the nested creation-time shape (countries/regions/cities/zips/metros).",
                        "oneOf": [
                          {
                            "items": {
                              "description": "ISO 3166-1 alpha-2 country code.",
                              "type": "string"
                            },
                            "type": "array"
                          },
                          {
                            "properties": {
                              "cities": {
                                "items": {
                                  "oneOf": [
                                    {
                                      "description": "The geo target constant id alone.",
                                      "type": "string"
                                    },
                                    {
                                      "properties": {
                                        "key": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "key"
                                      ],
                                      "type": "object"
                                    }
                                  ]
                                },
                                "type": "array"
                              },
                              "countries": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "metros": {
                                "items": {
                                  "oneOf": [
                                    {
                                      "description": "The geo target constant id alone.",
                                      "type": "string"
                                    },
                                    {
                                      "properties": {
                                        "key": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "key"
                                      ],
                                      "type": "object"
                                    }
                                  ]
                                },
                                "type": "array"
                              },
                              "regions": {
                                "items": {
                                  "oneOf": [
                                    {
                                      "description": "The geo target constant id alone.",
                                      "type": "string"
                                    },
                                    {
                                      "properties": {
                                        "key": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "key"
                                      ],
                                      "type": "object"
                                    }
                                  ]
                                },
                                "type": "array"
                              },
                              "zips": {
                                "items": {
                                  "oneOf": [
                                    {
                                      "description": "The geo target constant id alone.",
                                      "type": "string"
                                    },
                                    {
                                      "properties": {
                                        "key": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "key"
                                      ],
                                      "type": "object"
                                    }
                                  ]
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          }
                        ]
                      }
                    },
                    "type": "object"
                  }
                },
                "required": [
                  "targeting"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adGroupId": {
                      "description": "Demand Gen only: the ad group that received the locations and languages.",
                      "type": "string"
                    },
                    "campaignId": {
                      "type": "string"
                    },
                    "devices": {
                      "items": {
                        "properties": {
                          "bidModifier": {
                            "description": "Always null on this read; see GET's description.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "device": {
                            "enum": [
                              "MOBILE",
                              "DESKTOP",
                              "TABLET",
                              "CONNECTED_TV"
                            ],
                            "type": "string"
                          },
                          "included": {
                            "type": "boolean"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "excludedLocations": {
                      "description": "The negative (excluded) location criteria read back after the edit, same item shape as `locations`.",
                      "items": {
                        "properties": {
                          "canonicalName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "countryCode": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "geoTargetId": {
                            "type": "string"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "negative": {
                            "type": "boolean"
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "languages": {
                      "items": {
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "locationTargetingType": {
                      "description": "The value read back from Google after the edit.",
                      "enum": [
                        "presence",
                        "presence_or_interest",
                        null
                      ],
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "locations": {
                      "items": {
                        "properties": {
                          "canonicalName": {
                            "description": "Google's geo_target_constant.canonical_name; see GET's description.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "countryCode": {
                            "description": "Google's geo_target_constant.country_code; see GET's description.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "geoTargetId": {
                            "description": "Numeric id from Google's geoTargetConstants/{id}.",
                            "type": "string"
                          },
                          "name": {
                            "description": "Google's geo_target_constant.name; see GET's description.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "negative": {
                            "description": "true = excluded location.",
                            "type": "boolean"
                          },
                          "type": {
                            "description": "Google's geo_target_constant.target_type; see GET's description.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "updated": {
                      "description": "Which targeting fields were applied.",
                      "items": {
                        "enum": [
                          "devices",
                          "locations",
                          "excludedLocations",
                          "languages",
                          "locationTargetingType"
                        ],
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Targeting updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Edit a Google campaign's device, location, excluded location, or language targeting",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_campaign_targeting@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "ffa06784214c2ba7e70da23e980f31dfc6bce46d66a02d7211239e0e8efb5ea8"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_campaigns_campaignid_targeting",
          "method": "PUT",
          "path": "/apis/v1/ads/campaigns/{campaignId}/targeting"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_campaigns_campaignid_targeting"
      }
    },
    "/apis/v1/ads/catalogs": {
      "get": {
        "description": "Product Catalogs. Read only. Lists the Meta product catalogs a business portfolio owns or has been shared, for catalog and shopping ads. ### Which business The business comes from the first that applies: 1. `businessId` 2. the ad account's owner (`adAccountId`) 3. the WhatsApp Business Account's owner, when `connectionId` is a WhatsApp connection 4. the only business the Meta login can see ### Permission\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_catalogs",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account ID (act_...) whose owner business to list",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta business portfolio ID to list. When it is omitted and the Meta login can see several portfolios, the 400 carries `details.businesses` (id + name) so a client can offer the choice.",
            "in": "query",
            "name": "businessId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "businessId": {
                      "type": "string"
                    },
                    "catalogs": {
                      "items": {
                        "properties": {
                          "businessId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "productCount": {
                            "type": "integer"
                          },
                          "vertical": {
                            "description": "Catalog vertical as Meta reports it (e.g. commerce, services, vehicles, hotels)",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Catalogs"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List Meta product catalogs",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_catalogs@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e90b1d17584713a3f7ddf14a5a5c88956b96737e5295bd3b4bd9854210e2c7bf"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_catalogs",
          "method": "GET",
          "path": "/apis/v1/ads/catalogs"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_catalogs"
      },
      "post": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Creates a Meta product catalog that can power catalog ads, Instagram and Facebook Shops, and a WhatsApp Business catalog. Creates a Meta Commerce catalog in the business portfolio (resolved like GET). Needs catalog_management on the Meta login.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_catalogs",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Ad account whose owner business creates the catalog",
                    "type": "string"
                  },
                  "businessId": {
                    "description": "Business portfolio that owns the catalog",
                    "type": "string"
                  },
                  "catalogAccountId": {
                    "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 100,
                    "type": "string"
                  },
                  "vertical": {
                    "default": "commerce",
                    "description": "Meta catalog vertical. Use services for a professional services catalog (for example one linked to WhatsApp). local_service_business is a deprecated alias of local_service_businesses.",
                    "enum": [
                      "commerce",
                      "adoptable_pets",
                      "apps_and_software",
                      "articles_and_publications",
                      "destinations",
                      "flights",
                      "generic",
                      "home_listings",
                      "hotels",
                      "local_service_businesses",
                      "media_titles",
                      "offer_items",
                      "offline_commerce",
                      "services",
                      "transactable_items",
                      "vehicles",
                      "local_service_business"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "catalog": {
                      "properties": {
                        "businessId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "productCount": {
                          "type": "integer"
                        },
                        "vertical": {
                          "description": "Catalog vertical as Meta reports it (e.g. commerce, services, vehicles, hotels)",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Catalog created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a Meta product catalog",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_catalog@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0c8d669a151b0de236d7c8ab4ea1747a23f51a6e9dcde5dc977efb828b255388"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_catalogs",
          "method": "POST",
          "path": "/apis/v1/ads/catalogs"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_catalogs"
      }
    },
    "/apis/v1/ads/catalogs/{catalogId}": {
      "delete": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Deletes a Meta product catalog and all its products, removing it from any ads or WhatsApp numbers that use it. Ads and WhatsApp numbers that use it lose their catalog.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_catalogs_catalogid",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "catalogId": {
                      "type": "string"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete a product catalog",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_catalog@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "9eb0fddf05773c1946f791dce17980293e840896436f75f5e49b66bc9145f776"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_catalogs_catalogid",
          "method": "DELETE",
          "path": "/apis/v1/ads/catalogs/{catalogId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_catalogs_catalogid"
      },
      "get": {
        "description": "Product Catalogs. Read only. Shows one Meta product catalog and its details.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_catalogs_catalogid",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "catalog": {
                      "properties": {
                        "businessId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "productCount": {
                          "type": "integer"
                        },
                        "vertical": {
                          "description": "Catalog vertical as Meta reports it (e.g. commerce, services, vehicles, hotels)",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Catalog"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get a product catalog",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_catalog@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "87a3fadfab5fd3f7d9ffb6fee1e32d20de3b84f9ed6fdf3ce115fc4f47f3b7cf"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_catalogs_catalogid",
          "method": "GET",
          "path": "/apis/v1/ads/catalogs/{catalogId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_catalogs_catalogid"
      }
    },
    "/apis/v1/ads/catalogs/{catalogId}/batches/{handle}": {
      "get": {
        "description": "Product Catalogs. Read only. Shows whether a bulk catalog product request has finished, with any per-product errors.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_batch_8aff94",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Handle returned by the batch call",
            "in": "path",
            "name": "handle",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "batch": {
                      "properties": {
                        "errors": {
                          "items": {
                            "properties": {
                              "message": {
                                "type": "string"
                              },
                              "retailerId": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "errorsTotalCount": {
                          "type": "integer"
                        },
                        "handle": {
                          "type": "string"
                        },
                        "status": {
                          "description": "Meta's status, e.g. initial, in_progress, finished",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Batch status"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get a bulk request's status",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_catalog_batch@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "c708eb956cd606fa4963032e8043814e4578980735de20b33504221adec2fa5b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_batch_8aff94",
          "method": "GET",
          "path": "/apis/v1/ads/catalogs/{catalogId}/batches/{handle}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_catalogs_catalogid_batch_8aff94"
      }
    },
    "/apis/v1/ads/catalogs/{catalogId}/feeds": {
      "get": {
        "description": "Product Catalogs. Read only. Lists the product feeds that keep a Meta catalog filled from your product files.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_feeds",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "feeds": {
                      "items": {
                        "properties": {
                          "createdTime": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "type": "string"
                          },
                          "latestUpload": {
                            "oneOf": [
                              {
                                "properties": {
                                  "endTime": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "errorCount": {
                                    "type": "integer"
                                  },
                                  "id": {
                                    "type": "string"
                                  },
                                  "itemsDeleted": {
                                    "type": "integer"
                                  },
                                  "itemsDetected": {
                                    "type": "integer"
                                  },
                                  "startTime": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "url": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "warningCount": {
                                    "type": "integer"
                                  }
                                },
                                "type": "object"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "productCount": {
                            "type": "integer"
                          },
                          "schedule": {
                            "properties": {
                              "dayOfWeek": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "hour": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              },
                              "interval": {
                                "type": "string"
                              },
                              "url": {
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Feeds"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List a catalog's product feeds",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_catalog_feeds@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "da1e62d2091c7a2e4320091999316083763ac5cae56a0f121faf911d71231495"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_feeds",
          "method": "GET",
          "path": "/apis/v1/ads/catalogs/{catalogId}/feeds"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_catalogs_catalogid_feeds"
      },
      "post": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Creates a product feed that imports a CSV, TSV or XML product file into a Meta catalog, on a schedule or on demand. A feed pulls a CSV/TSV/XML product file from a URL. With `schedule` Meta fetches it on a cadence; without it, trigger fetches with POST /apis/v1/ads/catalogs/{catalogId}/feeds/{feedId}/uploads.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_feeds",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "catalogAccountId": {
                    "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 100,
                    "type": "string"
                  },
                  "schedule": {
                    "properties": {
                      "dayOfWeek": {
                        "enum": [
                          "SUNDAY",
                          "MONDAY",
                          "TUESDAY",
                          "WEDNESDAY",
                          "THURSDAY",
                          "FRIDAY",
                          "SATURDAY"
                        ],
                        "type": "string"
                      },
                      "hour": {
                        "maximum": 23,
                        "minimum": 0,
                        "type": "integer"
                      },
                      "interval": {
                        "enum": [
                          "HOURLY",
                          "DAILY",
                          "WEEKLY"
                        ],
                        "type": "string"
                      },
                      "url": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "required": [
                      "interval",
                      "url"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "feed": {
                      "properties": {
                        "createdTime": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "latestUpload": {
                          "oneOf": [
                            {
                              "properties": {
                                "endTime": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "errorCount": {
                                  "type": "integer"
                                },
                                "id": {
                                  "type": "string"
                                },
                                "itemsDeleted": {
                                  "type": "integer"
                                },
                                "itemsDetected": {
                                  "type": "integer"
                                },
                                "startTime": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "url": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "warningCount": {
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "name": {
                          "type": "string"
                        },
                        "productCount": {
                          "type": "integer"
                        },
                        "schedule": {
                          "properties": {
                            "dayOfWeek": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "hour": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            },
                            "interval": {
                              "type": "string"
                            },
                            "url": {
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Feed created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a product feed",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_catalog_feed@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "9fdbfccc2b0cbb0e5e52a5f426df99505b03bb64b6bd31dec2420d10d9c2dabd"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_feeds",
          "method": "POST",
          "path": "/apis/v1/ads/catalogs/{catalogId}/feeds"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_catalogs_catalogid_feeds"
      }
    },
    "/apis/v1/ads/catalogs/{catalogId}/feeds/{feedId}/uploads": {
      "get": {
        "description": "Product Catalogs. Read only. Lists a product feed's past file imports so you can check how each one went.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_feeds_d16892",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "feedId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "uploads": {
                      "items": {
                        "properties": {
                          "endTime": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "errorCount": {
                            "type": "integer"
                          },
                          "id": {
                            "type": "string"
                          },
                          "itemsDeleted": {
                            "type": "integer"
                          },
                          "itemsDetected": {
                            "type": "integer"
                          },
                          "startTime": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "url": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "warningCount": {
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Uploads, newest first"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List a feed's uploads",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_catalog_feed_uploads@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6db9dbded8442f0e697a4f50370c3d27e38a959af640c824e600cf1b614fc203"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_feeds_d16892",
          "method": "GET",
          "path": "/apis/v1/ads/catalogs/{catalogId}/feeds/{feedId}/uploads"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_catalogs_catalogid_feeds_d16892"
      },
      "post": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Asks Meta to import a product file into a feed right away instead of waiting for its schedule. Asks Meta to fetch the product file at `url` into the feed. Processing is asynchronous: read the outcome with GET uploads.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_feed_d16892",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "feedId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "url": "https://example.com/landing"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "catalogAccountId": {
                    "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "url": {
                    "format": "uri",
                    "type": "string"
                  }
                },
                "required": [
                  "url"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "upload": {
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Fetch started"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Fetch a feed file now",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_catalog_feed_upload@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "464de05d9c681ba4a7e7f53afc7484ae055ab3f9cbb6b2583621c313ea40ad81"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_feed_d16892",
          "method": "POST",
          "path": "/apis/v1/ads/catalogs/{catalogId}/feeds/{feedId}/uploads"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_catalogs_catalogid_feed_d16892"
      }
    },
    "/apis/v1/ads/catalogs/{catalogId}/product-sets": {
      "get": {
        "description": "Product Catalogs. Read only. Lists a Meta catalog's product sets, the groups of products a catalog ad promotes. Pass the chosen set id, not the parent catalog id, as `promotedObject.productSetId` on POST /apis/v1/ads/create with `goal: catalog_sales`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_product_sets",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "productSets": {
                      "items": {
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "productCount": {
                            "type": "integer"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Product sets"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List a catalog's product sets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_catalog_product_sets@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a2a67c053adf0bb1de1f0966be559f0268a9817e6052bd4a9609fc2a137c91a4"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_product_sets",
          "method": "GET",
          "path": "/apis/v1/ads/catalogs/{catalogId}/product-sets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_catalogs_catalogid_product_sets"
      },
      "post": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Creates a product set, a filtered group of catalog products (by SKU, brand and so on) to promote in catalog ads. A product set is a filter over the catalog, e.g. `{\"retailer_id\": {\"is_any\": [\"sku-1\", \"sku-2\"]}}` or `{\"brand\": {\"i_contains\": \"acme\"}}` (Meta's product set filter syntax).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_prod_f8fc1d",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "filter": {},
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "catalogAccountId": {
                    "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "filter": {
                    "additionalProperties": true,
                    "description": "Meta product set filter",
                    "type": "object"
                  },
                  "name": {
                    "maxLength": 100,
                    "type": "string"
                  }
                },
                "required": [
                  "filter",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "productSet": {
                      "properties": {
                        "filter": {
                          "additionalProperties": true,
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "productCount": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Product set created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a product set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_catalog_product_set@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "55b126a965465f1a01c49cb4c6a606b27086c6614430aea6fabba8825784a487"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_prod_f8fc1d",
          "method": "POST",
          "path": "/apis/v1/ads/catalogs/{catalogId}/product-sets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_catalogs_catalogid_prod_f8fc1d"
      }
    },
    "/apis/v1/ads/catalogs/{catalogId}/product-sets/{productSetId}": {
      "delete": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Deletes a product set from a Meta catalog.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_catalogs_catalogid_pr_5e4dc0",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "productSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "productSetId": {
                      "type": "string"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete a product set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_catalog_product_set@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "440b5ca7de9049c51ecc950ac0288f979fe2ba3014d3ee1c16d3d500b7e875c9"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_catalogs_catalogid_pr_5e4dc0",
          "method": "DELETE",
          "path": "/apis/v1/ads/catalogs/{catalogId}/product-sets/{productSetId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_catalogs_catalogid_pr_5e4dc0"
      },
      "put": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Changes a product set's name or the filter that decides which products it includes.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_catalogs_catalogid_produ_5e4dc0",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "productSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "catalogAccountId": "adc_7f3k2m9q",
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "catalogAccountId": {
                    "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "filter": {
                    "additionalProperties": true,
                    "type": "object"
                  },
                  "name": {
                    "maxLength": 100,
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "productSet": {
                      "properties": {
                        "filter": {
                          "additionalProperties": true,
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "productCount": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Product set updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update a product set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_catalog_product_set@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e5ce383427250a5347e51167e0c2b7698c364bcf559d42cd5c9a2dd90b452b7d"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_catalogs_catalogid_produ_5e4dc0",
          "method": "PUT",
          "path": "/apis/v1/ads/catalogs/{catalogId}/product-sets/{productSetId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_catalogs_catalogid_produ_5e4dc0"
      }
    },
    "/apis/v1/ads/catalogs/{catalogId}/products": {
      "get": {
        "description": "Product Catalogs. Read only. Lists the products in a Meta catalog, or looks one up by your own SKU. Filter by your own `retailerId` to look one up. `price` and `salePrice` come back formatted by Meta (for example \"€49.90\").\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_products",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from the previous page's `nextCursor`",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only the product with this retailer id (your SKU)",
            "in": "query",
            "name": "retailerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "products": {
                      "items": {
                        "properties": {
                          "additionalImageUrls": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "availability": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "brand": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "category": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "color": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "condition": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "currency": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "customLabels": {
                            "description": "custom_label_0 to custom_label_4",
                            "items": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "type": "array"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "gender": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "gtin": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "description": "Meta product item ID (use in the product endpoints)",
                            "type": "string"
                          },
                          "imageUrl": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "inventory": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "material": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "pattern": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "price": {
                            "description": "Formatted by Meta, e.g. \"€49.90\"",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "productType": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "retailerId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "reviewRejectionReasons": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "reviewStatus": {
                            "description": "Meta's commerce review status (approved, rejected, pending, ...)",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "salePrice": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "size": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "url": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "visibility": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Products"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List a catalog's products",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_catalog_products@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "8452f1016aaf46e15e2c44c103baffe4ff3890bb8de65b9535ecaebc4a2fe522"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_products",
          "method": "GET",
          "path": "/apis/v1/ads/catalogs/{catalogId}/products"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_catalogs_catalogid_products"
      },
      "post": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Adds a single product to a Meta catalog, keyed by your own SKU for later lookups and updates. `retailerId` is your SKU and stays the handle for later lookups and batch updates. For many products at once use POST /apis/v1/ads/catalogs/{catalogId}/products/batch. Needs catalog_management on the Meta login.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_products",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "product": {
                  "currency": "USD",
                  "imageUrl": "https://example.com/landing",
                  "name": "Winter launch",
                  "price": 10,
                  "retailerId": "1234567890",
                  "url": "https://example.com/landing"
                }
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "catalogAccountId": {
                    "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "product": {
                    "description": "One product shape for single and bulk calls.",
                    "properties": {
                      "additionalImageUrls": {
                        "items": {
                          "format": "uri",
                          "type": "string"
                        },
                        "maxItems": 20,
                        "type": "array"
                      },
                      "availability": {
                        "enum": [
                          "in stock",
                          "out of stock",
                          "preorder",
                          "available for order",
                          "discontinued",
                          "pending"
                        ],
                        "type": "string"
                      },
                      "brand": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "category": {
                        "maxLength": 250,
                        "type": "string"
                      },
                      "color": {
                        "maxLength": 200,
                        "type": "string"
                      },
                      "condition": {
                        "enum": [
                          "new",
                          "refurbished",
                          "used"
                        ],
                        "type": "string"
                      },
                      "currency": {
                        "description": "ISO 4217, e.g. EUR",
                        "type": "string"
                      },
                      "customLabel0": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "customLabel1": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "customLabel2": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "customLabel3": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "customLabel4": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "description": {
                        "maxLength": 9999,
                        "type": "string"
                      },
                      "gender": {
                        "enum": [
                          "female",
                          "male",
                          "unisex"
                        ],
                        "type": "string"
                      },
                      "googleProductCategory": {
                        "maxLength": 250,
                        "type": "string"
                      },
                      "gtin": {
                        "maxLength": 50,
                        "type": "string"
                      },
                      "imageUrl": {
                        "format": "uri",
                        "type": "string"
                      },
                      "inventory": {
                        "minimum": 0,
                        "type": "integer"
                      },
                      "material": {
                        "maxLength": 200,
                        "type": "string"
                      },
                      "mpn": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "name": {
                        "maxLength": 200,
                        "type": "string"
                      },
                      "pattern": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "price": {
                        "description": "Major units, e.g. 12.99",
                        "type": "number"
                      },
                      "productType": {
                        "maxLength": 750,
                        "type": "string"
                      },
                      "retailerId": {
                        "description": "Your SKU; unique inside the catalog",
                        "maxLength": 100,
                        "type": "string"
                      },
                      "salePrice": {
                        "type": "number"
                      },
                      "salePriceEndDate": {
                        "description": "ISO 8601",
                        "type": "string"
                      },
                      "salePriceStartDate": {
                        "description": "ISO 8601",
                        "type": "string"
                      },
                      "size": {
                        "maxLength": 200,
                        "type": "string"
                      },
                      "url": {
                        "description": "Product page",
                        "format": "uri",
                        "type": "string"
                      },
                      "visibility": {
                        "enum": [
                          "published",
                          "staging"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "currency",
                      "imageUrl",
                      "name",
                      "price",
                      "retailerId",
                      "url"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "product"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "product": {
                      "properties": {
                        "additionalImageUrls": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "availability": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "brand": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "color": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "condition": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "currency": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "customLabels": {
                          "description": "custom_label_0 to custom_label_4",
                          "items": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "type": "array"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "gender": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "gtin": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "description": "Meta product item ID (use in the product endpoints)",
                          "type": "string"
                        },
                        "imageUrl": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "inventory": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "material": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "name": {
                          "type": "string"
                        },
                        "pattern": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "price": {
                          "description": "Formatted by Meta, e.g. \"€49.90\"",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "productType": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retailerId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "reviewRejectionReasons": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "reviewStatus": {
                          "description": "Meta's commerce review status (approved, rejected, pending, ...)",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "salePrice": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "size": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "url": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "visibility": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Product created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Add a product to a catalog",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_catalog_product@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "8ca4c87388f2d20855d9ab8c78dc0e5e0a92f432928a005e68e8ecafdbcd40e6"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_products",
          "method": "POST",
          "path": "/apis/v1/ads/catalogs/{catalogId}/products"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_catalogs_catalogid_products"
      }
    },
    "/apis/v1/ads/catalogs/{catalogId}/products/batch": {
      "post": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Creates, updates or deletes up to 5,000 catalog products in one request, processed in the background by Meta. Up to 5000 CREATE / UPDATE / DELETE requests keyed by `retailerId`, processed asynchronously by Meta. Returns handles; poll GET /apis/v1/ads/catalogs/{catalogId}/batches/{handle} for the outcome and per-item errors. CREATE requests need name, url, imageUrl, price and currency.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_prod_9d9ec9",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "requests": [
                  {
                    "method": "CREATE",
                    "product": {
                      "retailerId": "1234567890"
                    }
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "catalogAccountId": {
                    "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "requests": {
                    "items": {
                      "properties": {
                        "method": {
                          "enum": [
                            "CREATE",
                            "UPDATE",
                            "DELETE"
                          ],
                          "type": "string"
                        },
                        "product": {
                          "description": "One product shape for single and bulk calls.",
                          "properties": {
                            "additionalImageUrls": {
                              "items": {
                                "format": "uri",
                                "type": "string"
                              },
                              "maxItems": 20,
                              "type": "array"
                            },
                            "availability": {
                              "enum": [
                                "in stock",
                                "out of stock",
                                "preorder",
                                "available for order",
                                "discontinued",
                                "pending"
                              ],
                              "type": "string"
                            },
                            "brand": {
                              "maxLength": 100,
                              "type": "string"
                            },
                            "category": {
                              "maxLength": 250,
                              "type": "string"
                            },
                            "color": {
                              "maxLength": 200,
                              "type": "string"
                            },
                            "condition": {
                              "enum": [
                                "new",
                                "refurbished",
                                "used"
                              ],
                              "type": "string"
                            },
                            "currency": {
                              "description": "ISO 4217, e.g. EUR",
                              "type": "string"
                            },
                            "customLabel0": {
                              "maxLength": 100,
                              "type": "string"
                            },
                            "customLabel1": {
                              "maxLength": 100,
                              "type": "string"
                            },
                            "customLabel2": {
                              "maxLength": 100,
                              "type": "string"
                            },
                            "customLabel3": {
                              "maxLength": 100,
                              "type": "string"
                            },
                            "customLabel4": {
                              "maxLength": 100,
                              "type": "string"
                            },
                            "description": {
                              "maxLength": 9999,
                              "type": "string"
                            },
                            "gender": {
                              "enum": [
                                "female",
                                "male",
                                "unisex"
                              ],
                              "type": "string"
                            },
                            "googleProductCategory": {
                              "maxLength": 250,
                              "type": "string"
                            },
                            "gtin": {
                              "maxLength": 50,
                              "type": "string"
                            },
                            "imageUrl": {
                              "format": "uri",
                              "type": "string"
                            },
                            "inventory": {
                              "minimum": 0,
                              "type": "integer"
                            },
                            "material": {
                              "maxLength": 200,
                              "type": "string"
                            },
                            "mpn": {
                              "maxLength": 100,
                              "type": "string"
                            },
                            "name": {
                              "maxLength": 200,
                              "type": "string"
                            },
                            "pattern": {
                              "maxLength": 100,
                              "type": "string"
                            },
                            "price": {
                              "description": "Major units, e.g. 12.99",
                              "type": "number"
                            },
                            "productType": {
                              "maxLength": 750,
                              "type": "string"
                            },
                            "retailerId": {
                              "description": "Your SKU; unique inside the catalog",
                              "maxLength": 100,
                              "type": "string"
                            },
                            "salePrice": {
                              "type": "number"
                            },
                            "salePriceEndDate": {
                              "description": "ISO 8601",
                              "type": "string"
                            },
                            "salePriceStartDate": {
                              "description": "ISO 8601",
                              "type": "string"
                            },
                            "size": {
                              "maxLength": 200,
                              "type": "string"
                            },
                            "url": {
                              "description": "Product page",
                              "format": "uri",
                              "type": "string"
                            },
                            "visibility": {
                              "enum": [
                                "published",
                                "staging"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "retailerId"
                          ],
                          "type": "object"
                        }
                      },
                      "required": [
                        "method",
                        "product"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5000,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "requests"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "handles": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "statusUrl": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Accepted by Meta"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create, update or delete products in bulk",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.batch_ad_catalog_products@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "549bbdced72385ebac7ad9970e36d969dc472306d728cb19b8a689e659bfd796"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_catalogs_catalogid_prod_9d9ec9",
          "method": "POST",
          "path": "/apis/v1/ads/catalogs/{catalogId}/products/batch"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_catalogs_catalogid_prod_9d9ec9"
      }
    },
    "/apis/v1/ads/catalogs/{catalogId}/products/{productId}": {
      "delete": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Removes one product from a Meta catalog.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_catalogs_catalogid_pr_0fcfd0",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta product item ID (from the products list; not the retailer id)",
            "in": "path",
            "name": "productId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "productId": {
                      "type": "string"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete a product",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_catalog_product@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "264367132bb6c16973013abbc4c6f604b09baae4699d456db5bdfb07c885f20b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_catalogs_catalogid_pr_0fcfd0",
          "method": "DELETE",
          "path": "/apis/v1/ads/catalogs/{catalogId}/products/{productId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_catalogs_catalogid_pr_0fcfd0"
      },
      "get": {
        "description": "Product Catalogs. Read only. Shows one product from a Meta catalog.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_produ_0fcfd0",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta product item ID (from the products list; not the retailer id)",
            "in": "path",
            "name": "productId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
            "in": "query",
            "name": "catalogAccountId",
            "required": false,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "product": {
                      "properties": {
                        "additionalImageUrls": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "availability": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "brand": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "color": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "condition": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "currency": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "customLabels": {
                          "description": "custom_label_0 to custom_label_4",
                          "items": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "type": "array"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "gender": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "gtin": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "description": "Meta product item ID (use in the product endpoints)",
                          "type": "string"
                        },
                        "imageUrl": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "inventory": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "material": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "name": {
                          "type": "string"
                        },
                        "pattern": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "price": {
                          "description": "Formatted by Meta, e.g. \"€49.90\"",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "productType": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retailerId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "reviewRejectionReasons": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "reviewStatus": {
                          "description": "Meta's commerce review status (approved, rejected, pending, ...)",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "salePrice": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "size": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "url": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "visibility": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Product"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get a product",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_catalog_product@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "d1229314ed8cfbe06021e790cbf084bf95a4eeae5ae56c53bb9b6d01c5dfd666"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_catalogs_catalogid_produ_0fcfd0",
          "method": "GET",
          "path": "/apis/v1/ads/catalogs/{catalogId}/products/{productId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_catalogs_catalogid_produ_0fcfd0"
      },
      "put": {
        "description": "Product Catalogs. Changes the ad account without starting or raising spend; audited. Changes some fields of a catalog product, such as its price or image, leaving the rest as they are. `retailerId` cannot change.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_catalogs_catalogid_produ_0fcfd0",
        "parameters": [
          {
            "description": "Meta product catalog ID (from GET /apis/v1/ads/catalogs)",
            "in": "path",
            "name": "catalogId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta product item ID (from the products list; not the retailer id)",
            "in": "path",
            "name": "productId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "product": {
                  "additionalImageUrls": [
                    "https://example.com/landing"
                  ],
                  "name": "Winter launch"
                }
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "catalogAccountId": {
                    "description": "One of your ads connections (adc_...) whose platform login manages the catalog, when it is not this connection's.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "product": {
                    "description": "One product shape for single and bulk calls.",
                    "properties": {
                      "additionalImageUrls": {
                        "items": {
                          "format": "uri",
                          "type": "string"
                        },
                        "maxItems": 20,
                        "type": "array"
                      },
                      "availability": {
                        "enum": [
                          "in stock",
                          "out of stock",
                          "preorder",
                          "available for order",
                          "discontinued",
                          "pending"
                        ],
                        "type": "string"
                      },
                      "brand": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "category": {
                        "maxLength": 250,
                        "type": "string"
                      },
                      "color": {
                        "maxLength": 200,
                        "type": "string"
                      },
                      "condition": {
                        "enum": [
                          "new",
                          "refurbished",
                          "used"
                        ],
                        "type": "string"
                      },
                      "currency": {
                        "description": "ISO 4217, e.g. EUR",
                        "type": "string"
                      },
                      "customLabel0": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "customLabel1": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "customLabel2": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "customLabel3": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "customLabel4": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "description": {
                        "maxLength": 9999,
                        "type": "string"
                      },
                      "gender": {
                        "enum": [
                          "female",
                          "male",
                          "unisex"
                        ],
                        "type": "string"
                      },
                      "googleProductCategory": {
                        "maxLength": 250,
                        "type": "string"
                      },
                      "gtin": {
                        "maxLength": 50,
                        "type": "string"
                      },
                      "imageUrl": {
                        "format": "uri",
                        "type": "string"
                      },
                      "inventory": {
                        "minimum": 0,
                        "type": "integer"
                      },
                      "material": {
                        "maxLength": 200,
                        "type": "string"
                      },
                      "mpn": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "name": {
                        "maxLength": 200,
                        "type": "string"
                      },
                      "pattern": {
                        "maxLength": 100,
                        "type": "string"
                      },
                      "price": {
                        "description": "Major units, e.g. 12.99",
                        "type": "number"
                      },
                      "productType": {
                        "maxLength": 750,
                        "type": "string"
                      },
                      "retailerId": {
                        "description": "Your SKU; unique inside the catalog",
                        "maxLength": 100,
                        "type": "string"
                      },
                      "salePrice": {
                        "type": "number"
                      },
                      "salePriceEndDate": {
                        "description": "ISO 8601",
                        "type": "string"
                      },
                      "salePriceStartDate": {
                        "description": "ISO 8601",
                        "type": "string"
                      },
                      "size": {
                        "maxLength": 200,
                        "type": "string"
                      },
                      "url": {
                        "description": "Product page",
                        "format": "uri",
                        "type": "string"
                      },
                      "visibility": {
                        "enum": [
                          "published",
                          "staging"
                        ],
                        "type": "string"
                      }
                    },
                    "type": "object"
                  }
                },
                "required": [
                  "product"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "product": {
                      "properties": {
                        "additionalImageUrls": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "availability": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "brand": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "color": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "condition": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "currency": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "customLabels": {
                          "description": "custom_label_0 to custom_label_4",
                          "items": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "type": "array"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "gender": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "gtin": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "description": "Meta product item ID (use in the product endpoints)",
                          "type": "string"
                        },
                        "imageUrl": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "inventory": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "material": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "name": {
                          "type": "string"
                        },
                        "pattern": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "price": {
                          "description": "Formatted by Meta, e.g. \"€49.90\"",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "productType": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retailerId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "reviewRejectionReasons": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "reviewStatus": {
                          "description": "Meta's commerce review status (approved, rejected, pending, ...)",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "salePrice": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "size": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "url": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "visibility": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Product updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update a product",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_catalog_product@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "eda3d168b242e750dc7f53864873a6d965d2311eac10596d63ebf48af0e84da0"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_catalogs_catalogid_produ_0fcfd0",
          "method": "PUT",
          "path": "/apis/v1/ads/catalogs/{catalogId}/products/{productId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_catalogs_catalogid_produ_0fcfd0"
      }
    },
    "/apis/v1/ads/connect/sessions/{sessionId}": {
      "get": {
        "description": "A connect session you started: its state and, once completed, the connection it made.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_connect_sessions_sessionid",
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "connectionId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "isUserFixable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "expiresAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "id": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "platform": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "state": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get a connect session",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.connection.get_connect_session@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "cdbe4d227e3197f483d7049575a69fe568ae0973a749cc518d62052a9efa5747"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_connect_sessions_sessionid",
          "method": "GET",
          "path": "/apis/v1/ads/connect/sessions/{sessionId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_connect_sessions_sessionid"
      }
    },
    "/apis/v1/ads/connect/tiktok/brand-identity": {
      "patch": {
        "description": "Connect. Changes the ad account without starting or raising spend; audited. TikTok requires every ad to carry an `identity_id + identity_type` pair. The Brand Identity is the CUSTOMIZED_USER alternative to attributing ads to a real @username (TT_USER). ### What this route does 1. Uploads the supplied image to TikTok. 2. Creates the identity via `/v2/identity/create/`. 3.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_connect_tiktok_brand_identity",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "displayName": "example",
                "imageUrl": "https://example.com/landing"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "displayName": {
                    "description": "Brand name shown above the ad on TikTok.",
                    "maxLength": 40,
                    "minLength": 1,
                    "type": "string"
                  },
                  "imageUrl": {
                    "description": "Public URL of a square brand image (≥98×98 px, JPG/PNG, max 5 MB). Used as the brand avatar on the ad.",
                    "format": "uri",
                    "type": "string"
                  }
                },
                "required": [
                  "displayName",
                  "imageUrl"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "displayName": {
                      "type": "string"
                    },
                    "identityId": {
                      "description": "The TikTok-assigned identity_id, cached on the account.",
                      "type": "string"
                    },
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Brand identity configured (or updated)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Set the TikTok brand identity of an ads-only connection",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.configure_tiktok_ads_brand_identity@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "481501a5cae9e2c3812ca2f1085ec30da35df478f1912427ba338cf32b0ad3dd"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_connect_tiktok_brand_identity",
          "method": "PATCH",
          "path": "/apis/v1/ads/connect/tiktok/brand-identity"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_connect_tiktok_brand_identity"
      }
    },
    "/apis/v1/ads/connect/{platform}": {
      "get": {
        "description": "Starts connecting an ad platform under one of your social profiles (the default when profileId is omitted). Open authUrl in a browser and poll the connect session; when the platform was already authorized under the profile the answer is the connection (alreadyConnected).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_connect_platform",
        "parameters": [
          {
            "in": "path",
            "name": "platform",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Your social profile (prf_...); the default profile when omitted.",
            "in": "query",
            "name": "profileId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Where the browser goes when the flow ends; it must be on your redirect allowlist.",
            "in": "query",
            "name": "redirectUrl",
            "required": false,
            "schema": {
              "format": "uri",
              "type": "string"
            }
          },
          {
            "description": "One of your social accounts (acc_...) on the profile. Required for X; on Meta, LinkedIn and Pinterest it picks the login the ads authorization reuses.",
            "in": "query",
            "name": "socialAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated platform ad account IDs to limit the connection to.",
            "in": "query",
            "name": "adAccountIds",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Always start a new authorization.",
            "in": "query",
            "name": "force",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "alreadyConnected": {
                      "type": [
                        "boolean",
                        "null"
                      ]
                    },
                    "authUrl": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "connectSessionId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "connection": {
                      "properties": {
                        "connectedAt": {
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "displayName": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platform": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "profileId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "syncedAt": {
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "username": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "expiresAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Connect an ad platform",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.connection.start_connect@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "da6fcfb0a67481c00285d0bd1d482c3bab78ff8b5bf9f99b279db148dcb56b49"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_connect_platform",
          "method": "GET",
          "path": "/apis/v1/ads/connect/{platform}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_connect_platform"
      }
    },
    "/apis/v1/ads/connect/{platform}/credentials": {
      "post": {
        "description": "Connects OpenAI Ads or Whop with the API key from that platform. The key is passed to the platform integration once; AIsa neither stores nor returns it.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_connect_platform_credentials",
        "parameters": [
          {
            "in": "path",
            "name": "platform",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "apiKey": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "profileId": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "connectedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "displayName": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "id": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "platform": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "profileId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "status": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "syncedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "username": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Connect an ad platform with an API key",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.connection.connect_with_credentials@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e315d18d599ede372094f1ff8689b1a1981ece9fff0725a90ac77be7261708d3"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_connect_platform_credentials",
          "method": "POST",
          "path": "/apis/v1/ads/connect/{platform}/credentials"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_connect_platform_credentials"
      }
    },
    "/apis/v1/ads/connections": {
      "get": {
        "description": "Your ads connections, refreshed from the platform integration at most once a minute (refresh=true forces it). Every catalogue operation runs on one of them, named by connectionId.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_connections",
        "parameters": [
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "refresh",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "properties": {
                          "connectedAt": {
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "displayName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platform": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "profileId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "syncedAt": {
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "username": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "type": [
                        "array",
                        "null"
                      ]
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List ads connections",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.connection.list_connections@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "cd99c4256d36a8e6415196016f020562a3ebd63428103d98342dc5f0d2c00135"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_connections",
          "method": "GET",
          "path": "/apis/v1/ads/connections"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_connections"
      }
    },
    "/apis/v1/ads/connections/{connectionId}": {
      "delete": {
        "description": "Removes the authorization at the ad platform integration and marks the connection disconnected. Campaigns keep running on the platform.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_connections_connectionid",
        "parameters": [
          {
            "in": "path",
            "name": "connectionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "connectedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "displayName": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "id": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "platform": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "profileId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "status": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "syncedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "username": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Disconnect an ads connection",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.connection.disconnect_connection@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "dfb32482d24c04f948fab1dab800c151102671ccc2bcfe5f5df630f8a7ba243f"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_connections_connectionid",
          "method": "DELETE",
          "path": "/apis/v1/ads/connections/{connectionId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_connections_connectionid"
      },
      "get": {
        "description": "One of your ads connections.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_connections_connectionid",
        "parameters": [
          {
            "in": "path",
            "name": "connectionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "connectedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "displayName": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "id": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "platform": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "profileId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "status": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "syncedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "username": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get an ads connection",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.connection.get_connection@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "63642b4ec81cb17ebc5d19c327c6fe28cf8883a7f3e87669a7c183bcc9a180fc"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_connections_connectionid",
          "method": "GET",
          "path": "/apis/v1/ads/connections/{connectionId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_connections_connectionid"
      }
    },
    "/apis/v1/ads/conversions": {
      "post": {
        "description": "Conversions. Changes the ad account without starting or raising spend; audited. Sends conversion events, such as purchases or leads, from your server to an ad platform so it can attribute and optimize ads. Relays one or more events to the target ad platform's native Conversions API. The platform is inferred from the provided `connectionId`. Requires the Ads add-on. ### Supported platforms Meta (`metaads`) via Graph API\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_conversions",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "destinationId": "1234567890",
                "events": [
                  {
                    "eventId": "1234567890",
                    "eventName": "example",
                    "eventTime": 10,
                    "user": {
                      "city": "example",
                      "clickIds": {
                        "epik": "example",
                        "fbc": "example"
                      }
                    }
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "consent": {
                    "description": "Batch-level user consent. Required by Google for EEA/UK events under the Feb 2026 restrictions.",
                    "properties": {
                      "adPersonalization": {
                        "enum": [
                          "GRANTED",
                          "DENIED"
                        ],
                        "type": "string"
                      },
                      "adUserData": {
                        "enum": [
                          "GRANTED",
                          "DENIED"
                        ],
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "destinationId": {
                    "description": "Platform destination identifier. For Meta, the pixel/dataset ID. For Google, the conversion action resource name. For LinkedIn, the conversion rule ID or full `urn:lla:llaPartnerConversion:{id}` URN. For OpenAI Ads, the pixel wire id.",
                    "type": "string"
                  },
                  "events": {
                    "items": {
                      "description": "A single conversion event to relay to the ad platform. Callers send plaintext.",
                      "properties": {
                        "actionSource": {
                          "description": "Where the conversion happened. Used by Meta. Google also requires an event source internally; omitting this field sends OTHER to Google. Send an explicit value for accurate origin reporting.",
                          "enum": [
                            "web",
                            "app",
                            "offline",
                            "crm",
                            "phone_call",
                            "system_generated",
                            "business_messaging"
                          ],
                          "type": "string"
                        },
                        "currency": {
                          "description": "ISO 4217 currency code.",
                          "type": "string"
                        },
                        "eventId": {
                          "description": "Unique dedup key. Use the same eventId on pixel + CAPI to prevent double-counting. Mapped to: Meta: event_id. Google: transactionId. LinkedIn: eventId.",
                          "type": "string"
                        },
                        "eventName": {
                          "description": "Standard event name (Purchase, Lead, CompleteRegistration, AddToCart, InitiateCheckout, AddPaymentInfo, Subscribe, StartTrial, ViewContent, Search, Contact, SubmitApplication, Schedule) or a custom string.",
                          "type": "string"
                        },
                        "eventTime": {
                          "description": "When the conversion happened, in unix seconds.",
                          "type": "integer"
                        },
                        "items": {
                          "description": "Item-level detail for ecommerce events.",
                          "items": {
                            "properties": {
                              "category": {
                                "type": "string"
                              },
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "price": {
                                "type": "number"
                              },
                              "quantity": {
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "messaging": {
                          "description": "Meta only, read when `actionSource` is `business_messaging` (Conversions API for Business Messaging). `channel` is sent as the event's `messaging_channel` (`instagram_direct` goes out as `instagram`).",
                          "properties": {
                            "channel": {
                              "enum": [
                                "whatsapp",
                                "messenger",
                                "instagram_direct"
                              ],
                              "type": "string"
                            },
                            "ctwaClid": {
                              "description": "WhatsApp only. Click-to-WhatsApp click id from the first inbound message referral, sent as `ctwa_clid`.",
                              "type": "string"
                            },
                            "instagramBusinessAccountId": {
                              "description": "Instagram Direct only. Instagram professional account id (`instagram_business_account` on the Page), sent as `ig_account_id` next to `ig_sid`.",
                              "type": "string"
                            },
                            "instagramScopedUserId": {
                              "description": "Instagram Direct only.",
                              "type": "string"
                            },
                            "pageId": {
                              "description": "Messenger: Facebook Page id, sent as `page_id`.",
                              "type": "string"
                            },
                            "pageScopedUserId": {
                              "description": "Messenger only.",
                              "type": "string"
                            },
                            "wabaId": {
                              "description": "WhatsApp only. WhatsApp Business Account id, sent as `whatsapp_business_account_id`.",
                              "type": "string"
                            }
                          },
                          "required": [
                            "channel"
                          ],
                          "type": "object"
                        },
                        "platformData": {
                          "additionalProperties": true,
                          "description": "Escape hatch for platform-specific fields we haven't normalized. Use first-class fields (e.g. `user.leadId`) for anything that must reach `user_data`.",
                          "type": "object"
                        },
                        "sourceUrl": {
                          "description": "URL where the conversion originated (used by Meta).",
                          "format": "uri",
                          "type": "string"
                        },
                        "user": {
                          "description": "User identity fields. More signals mean higher match rates.",
                          "properties": {
                            "city": {
                              "description": "Meta advanced matching (ct). Plaintext city; normalized + SHA-256 hashed server-side. Meta only.",
                              "type": "string"
                            },
                            "clickIds": {
                              "description": "Platform click identifiers captured from the originating ad click.",
                              "properties": {
                                "epik": {
                                  "description": "Pinterest click ID (the `epik` URL param or `_epik` cookie). Sent to Pinterest as `click_id`, not hashed.",
                                  "type": "string"
                                },
                                "fbc": {
                                  "description": "Meta click ID (from fbclid URL param).",
                                  "type": "string"
                                },
                                "fbp": {
                                  "description": "Meta browser ID (_fbp cookie).",
                                  "type": "string"
                                },
                                "gbraid": {
                                  "description": "Google iOS 14.5+ app attribution ID.",
                                  "type": "string"
                                },
                                "gclid": {
                                  "description": "Google click ID (from gclid URL param).",
                                  "type": "string"
                                },
                                "li_fat_id": {
                                  "description": "LinkedIn first-party ad tracking click ID. Captured by parsing `li_fat_id` from landing-page URLs after the advertiser enables enhanced conversion tracking on the LinkedIn Insight Tag.",
                                  "type": "string"
                                },
                                "rdt_cid": {
                                  "description": "Reddit click ID (the `rdt_cid` URL param Reddit adds to ad clicks). Sent to Reddit as `click_id`, not hashed.",
                                  "type": "string"
                                },
                                "rdt_uuid": {
                                  "description": "Reddit Pixel browser id (the `_rdt_uuid` first-party cookie). Sent to Reddit as `user.uuid`, not hashed.",
                                  "type": "string"
                                },
                                "wbraid": {
                                  "description": "Google iOS 14.5+ web-to-app attribution ID.",
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "country": {
                              "description": "ISO 3166-1 alpha-2 country code, e.g. 'us'.",
                              "type": "string"
                            },
                            "dob": {
                              "description": "Meta advanced matching (db). YYYYMMDD; hashed server-side. Meta only.",
                              "type": "string"
                            },
                            "email": {
                              "description": "Plaintext email. Hashed server-side.",
                              "type": "string"
                            },
                            "externalId": {
                              "description": "Stable customer identifier (e.g. CRM user ID). Hashed server-side for Meta and Google. Sent as plaintext to LinkedIn (LinkedIn's Conversions API spec requires the raw value). Maximum effective list size on LinkedIn is 1.",
                              "type": "string"
                            },
                            "firstName": {
                              "description": "Plaintext first name. Hashed server-side.",
                              "type": "string"
                            },
                            "gender": {
                              "description": "Meta advanced matching (ge). 'f' or 'm'; hashed server-side. Meta only.",
                              "type": "string"
                            },
                            "ipAddress": {
                              "description": "Client IP address. Sent plaintext.",
                              "type": "string"
                            },
                            "lastName": {
                              "description": "Plaintext last name. Hashed server-side.",
                              "type": "string"
                            },
                            "leadId": {
                              "description": "Meta lead ID from a Lead Ad submission, as a string. Required for Conversion Leads CRM events: send it with `actionSource: 'crm'` and `platformData: { event_source: 'crm', lead_event_source: '' }`.",
                              "type": "string"
                            },
                            "phone": {
                              "description": "Phone number, ideally E.164. Hashed server-side.",
                              "type": "string"
                            },
                            "state": {
                              "description": "Meta advanced matching (st). 2-letter ANSI for US; hashed server-side. Meta only.",
                              "type": "string"
                            },
                            "userAgent": {
                              "description": "Client user-agent string. Sent plaintext.",
                              "type": "string"
                            },
                            "zip": {
                              "description": "Meta advanced matching (zp). US uses first 5 digits; hashed server-side. Meta only.",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "value": {
                          "description": "Conversion value in the specified currency.",
                          "type": "number"
                        }
                      },
                      "required": [
                        "eventId",
                        "eventName",
                        "eventTime",
                        "user"
                      ],
                      "type": "object"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "testCode": {
                    "description": "Test event code. Send it at the request root, never inside an event. A root-level `test_event_code` (Meta's own name) is accepted as an alias and must be a non-empty string; sending both with different values is a 400.",
                    "type": "string"
                  }
                },
                "required": [
                  "destinationId",
                  "events"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "eventsFailed": {
                      "description": "Events rejected (see failures).",
                      "type": "integer"
                    },
                    "eventsReceived": {
                      "description": "Events accepted by the platform.",
                      "type": "integer"
                    },
                    "failures": {
                      "items": {
                        "properties": {
                          "code": {
                            "oneOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "integer"
                              }
                            ]
                          },
                          "eventId": {
                            "description": "Echoes back the eventId of the failed event.",
                            "type": "string"
                          },
                          "eventIndex": {
                            "description": "Index into the submitted events array.",
                            "type": "integer"
                          },
                          "message": {
                            "type": "string"
                          },
                          "platformError": {
                            "additionalProperties": true,
                            "description": "Meta only. Meta's own error for the rejected chunk, with credentials redacted: `message`, `type`, `code`, `error_subcode`, `error_user_title`, `error_user_msg` and `fbtrace_id` when Meta sends them.",
                            "type": "object"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "platform": {
                      "enum": [
                        "metaads",
                        "googleads",
                        "linkedinads",
                        "tiktokads",
                        "openaiads",
                        "pinterestads",
                        "redditads"
                      ],
                      "type": "string"
                    },
                    "testCode": {
                      "description": "The test code sent to the platform, as received (from `testCode` or `test_event_code`). `null` when the request carried none, so the events were sent as production events.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "traceId": {
                      "description": "Platform trace ID for debugging. fbtrace_id for Meta, requestId for Google. Absent for LinkedIn (LinkedIn's conversionEvents endpoint does not surface a trace ID), OpenAI Ads and Reddit (no trace ID surfaced).",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Events processed. Inspect `eventsFailed` and `failures[]` to detect partial failure."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Send conversion events",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.send_conversions@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "4994ef079a59d9084b7f59b3121d23d6ed039b27aca01442444779cbede0d1c3"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_conversions",
          "method": "POST",
          "path": "/apis/v1/ads/conversions"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_conversions"
      }
    },
    "/apis/v1/ads/conversions/actions": {
      "get": {
        "description": "Conversions. Read only. Lists the conversion actions in a Google Ads account, with the website tag snippets to install where available. Lists Google Ads conversion actions on the resolved customer, all types by default. Each action's `tagSnippets` (global site tag + event snippet) is included when Google has them for that action's type, e.g. `WEBPAGE`. Google-only; other platforms return `501`. Requires the Ads add-on.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_conversions_actions",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Resolved automatically when the connection has exactly one accessible customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by Google's ConversionActionType enum (e.g. WEBPAGE, UPLOAD_CLICKS).",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "actions": {
                      "items": {
                        "description": "A Google Ads conversion action, e.g. a WEBPAGE conversion created via `createConversionAction`. Returned by `listConversionActions` and `createConversionAction`.",
                        "properties": {
                          "alwaysUseDefaultValue": {
                            "description": "true = defaultValue is used even when the conversion sends its own value.",
                            "type": "boolean"
                          },
                          "category": {
                            "description": "Google's ConversionActionCategory, e.g. DEFAULT, PURCHASE, LEAD.",
                            "type": "string"
                          },
                          "clickThroughLookbackWindowDays": {
                            "description": "Days after an ad click a conversion is still credited (1 to 90).",
                            "type": "integer"
                          },
                          "countingType": {
                            "description": "Google's ConversionActionCountingType: ONE_PER_CLICK or MANY_PER_CLICK.",
                            "type": "string"
                          },
                          "defaultCurrency": {
                            "description": "ISO 4217 currency of defaultValue.",
                            "type": "string"
                          },
                          "defaultValue": {
                            "description": "Value recorded when the conversion carries none.",
                            "type": "number"
                          },
                          "id": {
                            "description": "Google Ads conversion action id.",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "origin": {
                            "description": "Google's ConversionOrigin, e.g. WEBSITE, APP. Together with category it names the goal the action belongs to (see GET /apis/v1/ads/conversions/goals).",
                            "type": "string"
                          },
                          "primaryForGoal": {
                            "description": "true = primary (counts toward bidding when its goal is biddable), false = secondary. Change it with PATCH /apis/v1/ads/conversions/actions/{actionId}.",
                            "type": "boolean"
                          },
                          "status": {
                            "description": "Google's ConversionActionStatus, e.g. ENABLED, REMOVED, HIDDEN.",
                            "type": "string"
                          },
                          "tagSnippets": {
                            "description": "The code a customer pastes onto their site. Present for types Google generates a snippet for (e.g. WEBPAGE); empty otherwise.",
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "type": {
                            "description": "Google's ConversionActionType, e.g. WEBPAGE, UPLOAD_CLICKS.",
                            "type": "string"
                          },
                          "viewThroughLookbackWindowDays": {
                            "description": "Days after an ad view a conversion is still credited (1 to 30).",
                            "type": "integer"
                          }
                        },
                        "required": [
                          "category",
                          "id",
                          "name",
                          "status",
                          "tagSnippets",
                          "type"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "cachedAt": {
                      "description": "When this list was fetched from Google. Null when it was never served from cache.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "description": "The Google Ads customer id the actions were read from.",
                      "type": "string"
                    },
                    "stale": {
                      "description": "True when Google's daily API quota was exhausted and this is the last successful fetch, not a live read.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The resolved customer and its conversion actions."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List conversion actions",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_conversion_actions@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "57228582f10196d53e3ad637a78cfcbebac3721f510be66e6e090250be3a4052"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_conversions_actions",
          "method": "GET",
          "path": "/apis/v1/ads/conversions/actions"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_conversions_actions"
      },
      "post": {
        "description": "Conversions. Changes the ad account without starting or raising spend; audited. Creates a Google Ads website conversion action and returns the tag snippets to install on your site. Creates a `WEBPAGE` conversion action (category `DEFAULT`) and returns it with its tag snippets, read back after creation since Google never returns them on the create response itself. Invalidates the cached list `GET` on this resource would otherwise keep serving.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_conversions_actions",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch",
                "type": "WEBPAGE"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Resolved automatically when the connection has exactly one accessible customer.",
                    "type": "string"
                  },
                  "alwaysUseDefaultValue": {
                    "description": "When true, always use defaultValue and ignore any value sent with the event. Defaults to true when defaultValue is set.",
                    "type": "boolean"
                  },
                  "category": {
                    "description": "conversion_action.category. Defaults to DEFAULT on create.",
                    "enum": [
                      "DEFAULT",
                      "PAGE_VIEW",
                      "PURCHASE",
                      "SIGNUP",
                      "DOWNLOAD",
                      "ADD_TO_CART",
                      "BEGIN_CHECKOUT",
                      "SUBSCRIBE_PAID",
                      "PHONE_CALL_LEAD",
                      "IMPORTED_LEAD",
                      "SUBMIT_LEAD_FORM",
                      "BOOK_APPOINTMENT",
                      "REQUEST_QUOTE",
                      "GET_DIRECTIONS",
                      "OUTBOUND_CLICK",
                      "CONTACT",
                      "ENGAGEMENT",
                      "STORE_VISIT",
                      "STORE_SALE",
                      "QUALIFIED_LEAD",
                      "CONVERTED_LEAD"
                    ],
                    "type": "string"
                  },
                  "clickThroughLookbackWindowDays": {
                    "description": "Days after an ad click a conversion still counts.",
                    "maximum": 90,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "countingType": {
                    "description": "ONE_PER_CLICK counts one conversion per ad click (leads); MANY_PER_CLICK counts every one (purchases).",
                    "enum": [
                      "ONE_PER_CLICK",
                      "MANY_PER_CLICK"
                    ],
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "type": "string"
                  },
                  "defaultCurrency": {
                    "description": "ISO 4217 currency of defaultValue (value_settings.default_currency_code).",
                    "pattern": "^[A-Z]{3}$",
                    "type": "string"
                  },
                  "defaultValue": {
                    "description": "Default conversion value used when an event doesn't carry its own value.",
                    "minimum": 0,
                    "type": "number"
                  },
                  "name": {
                    "maxLength": 100,
                    "minLength": 1,
                    "type": "string"
                  },
                  "primaryForGoal": {
                    "description": "true = primary (counts toward bidding when its goal is biddable), false = secondary.",
                    "type": "boolean"
                  },
                  "type": {
                    "description": "Only WEBPAGE is supported for creation today.",
                    "enum": [
                      "WEBPAGE"
                    ],
                    "type": "string"
                  },
                  "viewThroughLookbackWindowDays": {
                    "description": "Days after an ad view a view-through conversion still counts.",
                    "maximum": 30,
                    "minimum": 1,
                    "type": "integer"
                  }
                },
                "required": [
                  "name",
                  "type"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "action": {
                      "description": "A Google Ads conversion action, e.g. a WEBPAGE conversion created via `createConversionAction`. Returned by `listConversionActions` and `createConversionAction`.",
                      "properties": {
                        "alwaysUseDefaultValue": {
                          "description": "true = defaultValue is used even when the conversion sends its own value.",
                          "type": "boolean"
                        },
                        "category": {
                          "description": "Google's ConversionActionCategory, e.g. DEFAULT, PURCHASE, LEAD.",
                          "type": "string"
                        },
                        "clickThroughLookbackWindowDays": {
                          "description": "Days after an ad click a conversion is still credited (1 to 90).",
                          "type": "integer"
                        },
                        "countingType": {
                          "description": "Google's ConversionActionCountingType: ONE_PER_CLICK or MANY_PER_CLICK.",
                          "type": "string"
                        },
                        "defaultCurrency": {
                          "description": "ISO 4217 currency of defaultValue.",
                          "type": "string"
                        },
                        "defaultValue": {
                          "description": "Value recorded when the conversion carries none.",
                          "type": "number"
                        },
                        "id": {
                          "description": "Google Ads conversion action id.",
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "origin": {
                          "description": "Google's ConversionOrigin, e.g. WEBSITE, APP. Together with category it names the goal the action belongs to (see GET /apis/v1/ads/conversions/goals).",
                          "type": "string"
                        },
                        "primaryForGoal": {
                          "description": "true = primary (counts toward bidding when its goal is biddable), false = secondary. Change it with PATCH /apis/v1/ads/conversions/actions/{actionId}.",
                          "type": "boolean"
                        },
                        "status": {
                          "description": "Google's ConversionActionStatus, e.g. ENABLED, REMOVED, HIDDEN.",
                          "type": "string"
                        },
                        "tagSnippets": {
                          "description": "The code a customer pastes onto their site. Present for types Google generates a snippet for (e.g. WEBPAGE); empty otherwise.",
                          "items": {
                            "properties": {
                              "eventSnippet": {
                                "description": "The per-conversion-page snippet that fires the event.",
                                "type": "string"
                              },
                              "globalSiteTag": {
                                "description": "The gtag.js snippet to install once per site.",
                                "type": "string"
                              },
                              "pageFormat": {
                                "description": "Google's TrackingCodePageFormat, e.g. HTML, AMP.",
                                "type": "string"
                              },
                              "type": {
                                "description": "Google's TrackingCodeType, e.g. WEBPAGE.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "type"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "type": {
                          "description": "Google's ConversionActionType, e.g. WEBPAGE, UPLOAD_CLICKS.",
                          "type": "string"
                        },
                        "viewThroughLookbackWindowDays": {
                          "description": "Days after an ad view a conversion is still credited (1 to 30).",
                          "type": "integer"
                        }
                      },
                      "required": [
                        "category",
                        "id",
                        "name",
                        "status",
                        "tagSnippets",
                        "type"
                      ],
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The created conversion action, with its tag snippets."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create website conversion action",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_conversion_action@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "38b996883c04b877e9e80ab4e39d660d4bb75db667d417436d6da927014273e5"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_conversions_actions",
          "method": "POST",
          "path": "/apis/v1/ads/conversions/actions"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_conversions_actions"
      }
    },
    "/apis/v1/ads/conversions/actions/{actionId}": {
      "patch": {
        "description": "Conversions. Changes the ad account without starting or raising spend; audited. Changes a Google Ads conversion action's settings, such as primary or secondary, counting, value and lookback windows, or removes or restores it. Updates a Google Ads conversion action in one mutate, each field sent written on its own update mask leaf so omitted fields keep their value. Send at least one field.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_conversions_actions_actionid",
        "parameters": [
          {
            "description": "Google conversion action id",
            "in": "path",
            "name": "actionId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch",
                "status": "ENABLED"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Google customer id. Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "alwaysUseDefaultValue": {
                    "type": "boolean"
                  },
                  "category": {
                    "description": "conversion_action.category. Defaults to DEFAULT on create.",
                    "enum": [
                      "DEFAULT",
                      "PAGE_VIEW",
                      "PURCHASE",
                      "SIGNUP",
                      "DOWNLOAD",
                      "ADD_TO_CART",
                      "BEGIN_CHECKOUT",
                      "SUBSCRIBE_PAID",
                      "PHONE_CALL_LEAD",
                      "IMPORTED_LEAD",
                      "SUBMIT_LEAD_FORM",
                      "BOOK_APPOINTMENT",
                      "REQUEST_QUOTE",
                      "GET_DIRECTIONS",
                      "OUTBOUND_CLICK",
                      "CONTACT",
                      "ENGAGEMENT",
                      "STORE_VISIT",
                      "STORE_SALE",
                      "QUALIFIED_LEAD",
                      "CONVERTED_LEAD"
                    ],
                    "type": "string"
                  },
                  "clickThroughLookbackWindowDays": {
                    "description": "Days after an ad click a conversion still counts.",
                    "maximum": 90,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "countingType": {
                    "description": "ONE_PER_CLICK counts one conversion per ad click (leads); MANY_PER_CLICK counts every one (purchases).",
                    "enum": [
                      "ONE_PER_CLICK",
                      "MANY_PER_CLICK"
                    ],
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "defaultCurrency": {
                    "description": "ISO 4217 currency of defaultValue (value_settings.default_currency_code).",
                    "pattern": "^[A-Z]{3}$",
                    "type": "string"
                  },
                  "defaultValue": {
                    "minimum": 0,
                    "type": "number"
                  },
                  "name": {
                    "maxLength": 100,
                    "minLength": 1,
                    "type": "string"
                  },
                  "primaryForGoal": {
                    "description": "true = primary (counts toward bidding when its goal is biddable), false = secondary.",
                    "type": "boolean"
                  },
                  "status": {
                    "description": "REMOVED removes the action and must be sent alone; ENABLED restores a removed one.",
                    "enum": [
                      "ENABLED",
                      "REMOVED"
                    ],
                    "type": "string"
                  },
                  "viewThroughLookbackWindowDays": {
                    "description": "Days after an ad view a view-through conversion still counts.",
                    "maximum": 30,
                    "minimum": 1,
                    "type": "integer"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "action": {
                      "description": "The action id with the fields written, echoed back.",
                      "properties": {
                        "alwaysUseDefaultValue": {
                          "type": "boolean"
                        },
                        "category": {
                          "type": "string"
                        },
                        "clickThroughLookbackWindowDays": {
                          "type": "integer"
                        },
                        "countingType": {
                          "type": "string"
                        },
                        "defaultCurrency": {
                          "type": "string"
                        },
                        "defaultValue": {
                          "type": "number"
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "primaryForGoal": {
                          "type": "boolean"
                        },
                        "status": {
                          "type": "string"
                        },
                        "viewThroughLookbackWindowDays": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "customerId": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Action updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update a conversion action's settings",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_conversion_action@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "383e1789c2c96d55724d9f05aeb847454e93821c21eb54a3239f34a1e32f25cc"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_conversions_actions_actionid",
          "method": "PATCH",
          "path": "/apis/v1/ads/conversions/actions/{actionId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_conversions_actions_actionid"
      }
    },
    "/apis/v1/ads/conversions/adjustments": {
      "post": {
        "description": "Conversions. Changes the ad account without starting or raising spend; audited. Retracts, restates the value of, or enhances conversions you already sent to Google Ads, for refunds or late customer data. It adjusts conversions previously uploaded via `POST /apis/v1/ads/conversions`: retract them, restate their value, or enhance them with first-party data. Requires the Ads add-on. ### Google Ads only\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_conversions_adjustments",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adjustments": [
                  {
                    "adjustmentTime": 10,
                    "adjustmentType": "RETRACTION"
                  }
                ],
                "connectionId": "adc_7f3k2m9q",
                "destinationId": "1234567890"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adjustments": {
                    "items": {
                      "properties": {
                        "adjustmentTime": {
                          "description": "When the adjustment occurred, unix seconds.",
                          "type": "number"
                        },
                        "adjustmentType": {
                          "enum": [
                            "RETRACTION",
                            "RESTATEMENT",
                            "ENHANCEMENT"
                          ],
                          "type": "string"
                        },
                        "conversionTime": {
                          "description": "The original conversion's time, unix seconds. Required when identifying by `gclid`.",
                          "type": "number"
                        },
                        "currency": {
                          "description": "RESTATEMENT only. ISO 4217 currency for `restatementValue`.",
                          "type": "string"
                        },
                        "gclid": {
                          "description": "Alternative key. The original click ID. Pair with `conversionTime`. Not valid for ENHANCEMENT.",
                          "type": "string"
                        },
                        "orderId": {
                          "description": "Transaction ID of the original conversion (the `eventId` you sent). Recommended; required for ENHANCEMENT.",
                          "type": "string"
                        },
                        "restatementValue": {
                          "description": "RESTATEMENT only. The corrected TOTAL conversion value.",
                          "type": "number"
                        },
                        "user": {
                          "description": "ENHANCEMENT only. First-party identifiers (hashed server-side). At least one of email/phone required.",
                          "properties": {
                            "email": {
                              "type": "string"
                            },
                            "phone": {
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "userAgent": {
                          "description": "ENHANCEMENT only. The original conversion's user agent (improves match quality).",
                          "type": "string"
                        }
                      },
                      "required": [
                        "adjustmentTime",
                        "adjustmentType"
                      ],
                      "type": "object"
                    },
                    "maxItems": 2000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "destinationId": {
                    "description": "Conversion action resource name, e.g. `customers/1234567890/conversionActions/987654321`.",
                    "type": "string"
                  }
                },
                "required": [
                  "adjustments",
                  "destinationId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adjustmentsFailed": {
                      "description": "Adjustments rejected (see failures).",
                      "type": "integer"
                    },
                    "adjustmentsReceived": {
                      "description": "Adjustments accepted by Google.",
                      "type": "integer"
                    },
                    "failures": {
                      "items": {
                        "properties": {
                          "adjustmentIndex": {
                            "description": "Index into the submitted adjustments array.",
                            "type": "integer"
                          },
                          "code": {
                            "oneOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "integer"
                              }
                            ]
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "platform": {
                      "enum": [
                        "googleads"
                      ],
                      "type": "string"
                    },
                    "traceId": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Adjustments processed. Inspect `adjustmentsFailed` and `failures[]` for partial failure (Google reports per-row errors via partial failure)."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Adjust uploaded conversions",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.adjust_conversions@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "d1592c4c89d30fc389f0a43965d392b6638f2a373cfc2b33c9234e63f2c04ac5"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_conversions_adjustments",
          "method": "POST",
          "path": "/apis/v1/ads/conversions/adjustments"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_conversions_adjustments"
      }
    },
    "/apis/v1/ads/conversions/custom-goals": {
      "get": {
        "description": "Conversions. Read only. Lists the custom conversion goals in a Google Ads account, each a named set of conversion actions a campaign can bid on. Google Ads custom conversion goals (a named set of conversion actions a campaign can bid on). Removed goals are excluded. Cached like the other Google reads.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_conversions_custom_goals",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google customer id. Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "goals": {
                      "items": {
                        "properties": {
                          "conversionActionIds": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "resourceName": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Custom conversion goals"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List custom conversion goals",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_custom_conversion_goals@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "20a9974039a94abb13440b0a9605cc45903aa3855777210ba0b91b3657a8f8fc"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_conversions_custom_goals",
          "method": "GET",
          "path": "/apis/v1/ads/conversions/custom-goals"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_conversions_custom_goals"
      },
      "post": {
        "description": "Conversions. Changes the ad account without starting or raising spend; audited. Creates a Google Ads custom conversion goal from a set of conversion actions, so a campaign can bid on just those. Creates a custom conversion goal from conversion action ids. Point a campaign at it with `PATCH /apis/v1/ads/campaigns/{campaignId}/conversion-goals`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_conversions_custom_goals",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "conversionActionIds": [
                  "1234567890"
                ],
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Google customer id. Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "conversionActionIds": {
                    "items": {
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "type": "array"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "required": [
                  "conversionActionIds",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    },
                    "resourceName": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Custom goal created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a custom conversion goal",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_custom_conversion_goal@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "ce8a93a91757b6e004b319fb7f32c2144995a37d0b142d8a420a8bc99d2aa01a"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_conversions_custom_goals",
          "method": "POST",
          "path": "/apis/v1/ads/conversions/custom-goals"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_conversions_custom_goals"
      }
    },
    "/apis/v1/ads/conversions/custom-goals/{goalId}": {
      "delete": {
        "description": "Conversions. Changes the ad account without starting or raising spend; audited. Deletes a Google Ads custom conversion goal; switch any campaigns using it to another goal first. Google refuses (400) while any campaign still uses it: switch those campaigns to another goal first.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_conversions_custom_go_047de4",
        "parameters": [
          {
            "description": "Google custom conversion goal id",
            "in": "path",
            "name": "goalId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google customer id. Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "goalId": {
                      "type": "string"
                    },
                    "removed": {
                      "description": "Always true on success",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Custom goal removed"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove a custom conversion goal",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_custom_conversion_goal@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e3a2a19222c5aba4b6bfc72a50e0aa68d70548ba8a66fef9f0861f4efe142f19"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_conversions_custom_go_047de4",
          "method": "DELETE",
          "path": "/apis/v1/ads/conversions/custom-goals/{goalId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_conversions_custom_go_047de4"
      },
      "patch": {
        "description": "Conversions. Changes the ad account without starting or raising spend; audited. Renames a Google Ads custom conversion goal or replaces the conversion actions in it. Returns the re-read goal.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_conversions_custom_goa_047de4",
        "parameters": [
          {
            "description": "Google custom conversion goal id",
            "in": "path",
            "name": "goalId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Google customer id. Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "conversionActionIds": {
                    "description": "Replaces the whole set.",
                    "items": {
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "type": "array"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "goal": {
                      "properties": {
                        "conversionActionIds": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "resourceName": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Custom goal updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update a custom conversion goal",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_custom_conversion_goal@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "b363b608cdd87a66c3cca282b76c8c713f824563ed3a576e8ac491d064ab23a9"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_conversions_custom_goa_047de4",
          "method": "PATCH",
          "path": "/apis/v1/ads/conversions/custom-goals/{goalId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_conversions_custom_goa_047de4"
      }
    },
    "/apis/v1/ads/conversions/goals": {
      "get": {
        "description": "Conversions. Read only. Lists a Google Ads account's default conversion goals, which ones are used for bidding, and the conversion actions in each. These are Google Ads account-default conversion goals (CustomerConversionGoal), one per category and origin. Each goal carries: `biddable`: whether the goal is used for bidding and reported in the Conversions column.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_conversions_goals",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google customer id. Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "goals": {
                      "items": {
                        "properties": {
                          "biddable": {
                            "description": "Used for bidding and counted in the Conversions column.",
                            "type": "boolean"
                          },
                          "category": {
                            "type": "string"
                          },
                          "conversionActions": {
                            "description": "Non-removed conversion actions in this category and origin.",
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "origin": {
                            "type": "string"
                          },
                          "resourceName": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Account conversion goals"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List account conversion goals",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_conversion_goals@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "cdfec80262fa27a44eeda7471f5e9e31dd5a3085b046acdddb6e9f070b5c57c7"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_conversions_goals",
          "method": "GET",
          "path": "/apis/v1/ads/conversions/goals"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_conversions_goals"
      },
      "patch": {
        "description": "Conversions. Changes the ad account without starting or raising spend; audited. Turns bidding on or off for a Google Ads account's default conversion goals, which campaigns using account goals follow. Sets `biddable` on one or more account-default goals, addressed by category and origin, in one mutate. Campaigns that use account-level goals (`goalConfigLevel: CUSTOMER`) follow the change. Returns the re-read goal list.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_conversions_goals",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "goals": [
                  {
                    "biddable": false,
                    "category": "EXAMPLE",
                    "origin": "EXAMPLE"
                  }
                ]
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Google customer id. Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "goals": {
                    "items": {
                      "additionalProperties": false,
                      "properties": {
                        "biddable": {
                          "type": "boolean"
                        },
                        "category": {
                          "description": "Google ConversionActionCategory, e.g. PURCHASE, SIGNUP, SUBMIT_LEAD_FORM",
                          "pattern": "^[A-Z][A-Z0-9_]*$",
                          "type": "string"
                        },
                        "origin": {
                          "description": "Google ConversionOrigin, e.g. WEBSITE, APP, CALL_FROM_ADS, STORE, GOOGLE_HOSTED",
                          "pattern": "^[A-Z][A-Z0-9_]*$",
                          "type": "string"
                        }
                      },
                      "required": [
                        "biddable",
                        "category",
                        "origin"
                      ],
                      "type": "object"
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "goals"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "goals": {
                      "items": {
                        "properties": {
                          "biddable": {
                            "description": "Used for bidding and counted in the Conversions column.",
                            "type": "boolean"
                          },
                          "category": {
                            "type": "string"
                          },
                          "conversionActions": {
                            "description": "Non-removed conversion actions in this category and origin.",
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "origin": {
                            "type": "string"
                          },
                          "resourceName": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Goals updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update account conversion goals",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_conversion_goals@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "032bc991d68eb4cce24252710c6f6648b37fbd2b8a84976644bf50ec05dc663b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_conversions_goals",
          "method": "PATCH",
          "path": "/apis/v1/ads/conversions/goals"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_conversions_goals"
      }
    },
    "/apis/v1/ads/conversions/quality": {
      "get": {
        "description": "Conversions. Read only. Shows how well your server-side conversion events match users, with event match quality and coverage for Meta or Pinterest. Reads Meta Event Match Quality (EMQ) and pixel↔CAPI event coverage for a pixel/dataset, live from Meta's Dataset Quality API. Web events only (a Meta limitation). Other platforms return 405, except Pinterest. Requires the Ads add-on.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_conversions_quality",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta pixel/dataset ID, or the numeric Pinterest ad account id.",
            "in": "query",
            "name": "destinationId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "platform": {
                      "type": "string"
                    },
                    "rows": {
                      "items": {
                        "properties": {
                          "compositeScore": {
                            "description": "Composite EMQ score, 0-10.",
                            "type": "number"
                          },
                          "eventCoveragePercentage": {
                            "description": "Pixel↔CAPI coverage rate for this event.",
                            "type": "number"
                          },
                          "eventName": {
                            "type": "string"
                          },
                          "matchKeys": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Match-quality rows, one per event name."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get Event Match Quality",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_conversions_quality@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "9725aa4357f40bda5f32bfdd8974e09168cc02493efd99ff5a8a0a8ad035512f"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_conversions_quality",
          "method": "GET",
          "path": "/apis/v1/ads/conversions/quality"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_conversions_quality"
      }
    },
    "/apis/v1/ads/create": {
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates a campaign, ad set and ad in one call; it spends its budget once the platform approves it. validateOnly=true checks the request without acting and needs no confirmation. Creates a paid ad with your own creative, building the campaign and ad set it needs or adding it to existing ones. Works across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, OpenAI Ads (ChatGPT Ads) and Reddit Ads. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. ### Request shapes The body selects one of these mutually exclusive shapes:\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_create",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "9122445560",
                "body": "Same-day repairs across Lyon.",
                "budgetAmount": 5,
                "budgetType": "daily",
                "campaignType": "search",
                "cities": [
                  "1006410"
                ],
                "connectionId": "adc_7f3k2m9q",
                "goal": "traffic",
                "headline": "Plumber in Lyon",
                "keywords": [
                  "plombier lyon"
                ],
                "linkUrl": "https://example.com",
                "locationTargetingType": "presence",
                "name": "Lyon plumbing",
                "status": "PAUSED"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "type": "string"
                  },
                  "adName": {
                    "description": "Meta only. Exact ad name (the single-creative ad object's name). Overrides the default, which is `name`. (For per-ad names on the multi-creative shape, set `name` on each `creatives[]` entry instead.)",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "adSetId": {
                    "description": "When present, switches to the attach shape: adds one new ad to this existing ad set without creating a new campaign. Mutually exclusive with `creatives[]`. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "adSetName": {
                    "description": "Exact ad set name. Meta, Reddit and Google (the ad group). Overrides the default ` - Ad Set` (Google Search and Display: ` - Ad Group`). Ignored when the request joins an existing ad set (`adSetId`).",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "adSetStatus": {
                    "description": "Every platform. Sets the switch of the new ad set alone and overrides `status` for it. When omitted, it follows `status`.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "adStatus": {
                    "description": "Request-side publish switch for `adStatus` on ad creation endpoints only (`status`, `campaignStatus` and `adSetStatus` carry their own inline ACTIVE/PAUSED enum there; the status-update endpoints are a separate lowercase `active`/`paused`…",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "additionalDescriptions": {
                    "description": "Google Search RSA only. Extra text assets, as strings or objects with text and optional pinnedField. Existing string input remains supported.",
                    "items": {
                      "oneOf": [
                        {
                          "maxLength": 90,
                          "minLength": 1,
                          "type": "string"
                        },
                        {
                          "properties": {
                            "pinnedField": {
                              "description": "Optional fixed description position. Omit to leave the asset unpinned.",
                              "enum": [
                                "DESCRIPTION_1",
                                "DESCRIPTION_2"
                              ],
                              "type": "string"
                            },
                            "text": {
                              "maxLength": 90,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "type": "array"
                  },
                  "additionalHeadlines": {
                    "description": "Google Search RSA only. Extra text assets, as strings or objects with text and optional pinnedField. String input remains supported.",
                    "items": {
                      "oneOf": [
                        {
                          "maxLength": 30,
                          "minLength": 1,
                          "type": "string"
                        },
                        {
                          "properties": {
                            "pinnedField": {
                              "description": "Optional fixed headline position. Omit to leave the asset unpinned.",
                              "enum": [
                                "HEADLINE_1",
                                "HEADLINE_2",
                                "HEADLINE_3"
                              ],
                              "type": "string"
                            },
                            "text": {
                              "maxLength": 30,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "type": "array"
                  },
                  "advantageAudience": {
                    "description": "Meta only. Controls the Advantage audience feature (targeting_automation). 0 = disabled (default), 1 = enabled. Meta Marketing API requires this field on all ad set creation requests.",
                    "enum": [
                      0,
                      1
                    ],
                    "type": "integer"
                  },
                  "ageMax": {
                    "maximum": 65,
                    "minimum": 13,
                    "type": "integer"
                  },
                  "ageMin": {
                    "maximum": 65,
                    "minimum": 13,
                    "type": "integer"
                  },
                  "aiDisclosure": {
                    "description": "Meta only. Meta's \"Ad includes media created or edited with AI\" disclosure (the Ads Manager checkbox), stored on the creative as `generative_asset_spec.transparency_metadata.self_disclosure`. OPT_IN: checks it.",
                    "enum": [
                      "OPT_IN",
                      "OPT_OUT"
                    ],
                    "type": "string"
                  },
                  "assetGroup": {
                    "additionalProperties": false,
                    "description": "Google Performance Max creative assets. At least one description must be 60 characters or fewer. Texts within each list must be distinct.",
                    "properties": {
                      "businessName": {
                        "maxLength": 25,
                        "minLength": 1,
                        "type": "string"
                      },
                      "descriptions": {
                        "description": "At least one description must be 60 characters or fewer.",
                        "items": {
                          "maxLength": 90,
                          "minLength": 1,
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 2,
                        "type": "array",
                        "uniqueItems": true
                      },
                      "finalUrl": {
                        "description": "Required destination URL.",
                        "format": "uri",
                        "pattern": "^https?://",
                        "type": "string"
                      },
                      "headlines": {
                        "items": {
                          "maxLength": 30,
                          "minLength": 1,
                          "type": "string"
                        },
                        "maxItems": 15,
                        "minItems": 3,
                        "type": "array",
                        "uniqueItems": true
                      },
                      "images": {
                        "additionalProperties": false,
                        "description": "Public HTTP(S) image URLs. GIF, JPEG or PNG, at most 5120 KB per image. Google validates dimensions and aspect ratios.",
                        "properties": {
                          "landscape": {
                            "description": "Landscape marketing images. Aspect ratio 1.91:1, minimum 600 x 314 pixels.",
                            "items": {
                              "format": "uri",
                              "pattern": "^https?://",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "logo": {
                            "description": "Required square logos. Aspect ratio 1:1, minimum 128 x 128 pixels.",
                            "items": {
                              "format": "uri",
                              "pattern": "^https?://",
                              "type": "string"
                            },
                            "maxItems": 5,
                            "minItems": 1,
                            "type": "array"
                          },
                          "square": {
                            "description": "Square marketing images. Aspect ratio 1:1, minimum 300 x 300 pixels.",
                            "items": {
                              "format": "uri",
                              "pattern": "^https?://",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          }
                        },
                        "required": [
                          "landscape",
                          "logo",
                          "square"
                        ],
                        "type": "object"
                      },
                      "longHeadline": {
                        "maxLength": 90,
                        "minLength": 1,
                        "type": "string"
                      },
                      "name": {
                        "description": "Defaults to the request name.",
                        "maxLength": 128,
                        "minLength": 1,
                        "type": "string"
                      },
                      "youtubeVideoId": {
                        "description": "Optional existing YouTube video id. Google can generate video when omitted. Video uploads and arbitrary video URLs are not supported.",
                        "pattern": "^[A-Za-z0-9_-]{11}$",
                        "type": "string"
                      }
                    },
                    "required": [
                      "businessName",
                      "descriptions",
                      "finalUrl",
                      "headlines",
                      "images",
                      "longHeadline"
                    ],
                    "type": "object"
                  },
                  "attributionSpec": {
                    "description": "Meta only. Conversion attribution window for the ad set, mapping 1:1 to Meta's ad-set `attribution_spec`. Only honored for conversion goals (`conversions`, `lead_generation`, `app_promotion`); ignored for awareness/traffic/engagement.",
                    "items": {
                      "properties": {
                        "eventType": {
                          "enum": [
                            "CLICK_THROUGH",
                            "VIEW_THROUGH",
                            "ENGAGED_VIDEO_VIEW"
                          ],
                          "type": "string"
                        },
                        "windowDays": {
                          "enum": [
                            1,
                            7,
                            28
                          ],
                          "type": "integer"
                        }
                      },
                      "required": [
                        "eventType",
                        "windowDays"
                      ],
                      "type": "object"
                    },
                    "maxItems": 3,
                    "minItems": 1,
                    "type": "array"
                  },
                  "audienceId": {
                    "description": "Custom audience ID for targeting Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "behaviors": {
                    "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). Each must include id. On TikTok:",
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "bidAmount": {
                    "description": "Deprecated: send it inside `platformSpecificData` instead (Meta today; TikTok's nested shape is planned). The flat field keeps working during the deprecation window; sending both shapes returns a 400.",
                    "type": "number"
                  },
                  "bidStrategy": {
                    "description": "Deprecated: send it inside `platformSpecificData` instead (Meta today; TikTok's nested shape is planned). The flat field keeps working during the deprecation window. Sending both shapes returns a 400.",
                    "enum": [
                      "LOWEST_COST_WITHOUT_CAP",
                      "LOWEST_COST_WITH_BID_CAP",
                      "COST_CAP",
                      "LOWEST_COST_WITH_MIN_ROAS"
                    ],
                    "type": "string"
                  },
                  "billingEvent": {
                    "description": "Meta only. Explicit ad-set `billing_event`. Defaults to `IMPRESSIONS`. Forwarded verbatim to Meta, which validates compatibility with the optimization goal.",
                    "type": "string"
                  },
                  "boardId": {
                    "description": "Pinterest only. Board ID (auto-creates if not provided).",
                    "type": "string"
                  },
                  "bodies": {
                    "description": "Meta only. Multiple Text Options (Advantage+ Flexible Format): 1-5 primary-text variations that Meta optimises delivery across, WITHOUT enabling full Dynamic Creative (`dynamicCreative`).",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 5,
                    "minItems": 1,
                    "type": "array"
                  },
                  "body": {
                    "description": "Required on legacy + attach shapes. X: the tweet text (max 280 chars including a ~24-char URL when `linkUrl` is set). LinkedIn: the post commentary (the intro text shown above the ad). OpenAI Ads: the chat card's body text.",
                    "type": "string"
                  },
                  "brandIdentity": {
                    "description": "TikTok only; non-TikTok platforms ignore this field. Synthetic Brand Identity used when the ad attributes to a CUSTOMIZED_USER (instead of a real TT_USER @username).",
                    "properties": {
                      "displayName": {
                        "description": "Brand name shown above the ad on TikTok.",
                        "maxLength": 40,
                        "minLength": 1,
                        "type": "string"
                      },
                      "imageUrl": {
                        "description": "Public URL of a square brand image (≥98×98 px, JPG/PNG). Used as the brand avatar on the ad.",
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "required": [
                      "displayName",
                      "imageUrl"
                    ],
                    "type": "object"
                  },
                  "budgetAmount": {
                    "description": "Budget in WHOLE currency units (USD: 50 = $50.00), NOT cents. Meta's own Marketing API takes this number in minor units, an easy and expensive mix-up. Required on legacy, multi-creative and Performance Max shapes. Inherited on attach.",
                    "type": "number"
                  },
                  "budgetLevel": {
                    "default": "adset",
                    "description": "Meta only. Where the budget lives, which selects the Meta budget model: `adset` (default): ABO (Ad-set Budget Optimization). The budget is set on the ad set. Back-compatible; omit this field to keep it.",
                    "enum": [
                      "adset",
                      "campaign"
                    ],
                    "type": "string"
                  },
                  "budgetType": {
                    "description": "Defaults to daily when `budgetAmount` is sent without it (reported in `appliedDefaults.budgetType`). Inherited on attach. OpenAI Ads: accepts both as the campaign's single spend cap.",
                    "enum": [
                      "daily",
                      "lifetime"
                    ],
                    "type": "string"
                  },
                  "businessName": {
                    "description": "Google Display only",
                    "maxLength": 25,
                    "type": "string"
                  },
                  "buyingType": {
                    "default": "AUCTION",
                    "description": "Meta only. Buying type. Defaults to AUCTION and is explicitly sent on new campaigns, including validateOnly. Reusing existingCampaignId does not change the campaign. RESERVED = Reach & Frequency:",
                    "enum": [
                      "AUCTION",
                      "RESERVED"
                    ],
                    "type": "string"
                  },
                  "callToAction": {
                    "description": "The ad's call-to-action button. Meta: required on legacy + attach shapes. Accepts every call to action type Meta itself accepts (the enum lists them), including values such as SEE_DETAILS that ads synced from Meta carry.",
                    "enum": [
                      "BOOK_TRAVEL",
                      "CONTACT_US",
                      "DONATE",
                      "DONATE_NOW",
                      "DOWNLOAD",
                      "GET_DIRECTIONS",
                      "GO_LIVE",
                      "INTERESTED",
                      "LEARN_MORE",
                      "SEE_DETAILS",
                      "LIKE_PAGE",
                      "MESSAGE_PAGE",
                      "RAISE_MONEY",
                      "SAVE",
                      "SEND_TIP",
                      "SHOP_NOW",
                      "SIGN_UP",
                      "VIEW_INSTAGRAM_PROFILE",
                      "INSTAGRAM_MESSAGE",
                      "LOYALTY_LEARN_MORE",
                      "PURCHASE_GIFT_CARDS",
                      "PAY_TO_ACCESS",
                      "SEE_MORE",
                      "TRY_IN_CAMERA",
                      "WHATSAPP_LINK",
                      "GET_IN_TOUCH",
                      "TRY_NOW",
                      "ASK_A_QUESTION",
                      "START_A_CHAT",
                      "CHAT_NOW",
                      "ASK_US",
                      "CHAT_WITH_US",
                      "SHOP_ON_RETAILER",
                      "BOOK_NOW",
                      "CHECK_AVAILABILITY",
                      "ORDER_NOW",
                      "WHATSAPP_MESSAGE",
                      "GET_MOBILE_APP",
                      "INSTALL_MOBILE_APP",
                      "USE_MOBILE_APP",
                      "INSTALL_APP",
                      "USE_APP",
                      "PLAY_GAME",
                      "TRY_DEMO",
                      "WATCH_VIDEO",
                      "WATCH_MORE",
                      "OPEN_LINK",
                      "NO_BUTTON",
                      "LISTEN_MUSIC",
                      "MOBILE_DOWNLOAD",
                      "GET_OFFER",
                      "GET_OFFER_VIEW",
                      "BUY_NOW",
                      "BUY_TICKETS",
                      "UPDATE_APP",
                      "BET_NOW",
                      "ADD_TO_CART",
                      "SELL_NOW",
                      "GET_SHOWTIMES",
                      "LISTEN_NOW",
                      "GET_EVENT_TICKETS",
                      "REMIND_ME",
                      "SEARCH_MORE",
                      "PRE_REGISTER",
                      "SWIPE_UP_PRODUCT",
                      "SWIPE_UP_SHOP",
                      "PLAY_GAME_ON_FACEBOOK",
                      "VISIT_WORLD",
                      "OPEN_INSTANT_APP",
                      "JOIN_GROUP",
                      "GET_PROMOTIONS",
                      "SEND_UPDATES",
                      "INQUIRE_NOW",
                      "VISIT_PROFILE",
                      "CHAT_ON_WHATSAPP",
                      "EXPLORE_MORE",
                      "CONFIRM",
                      "JOIN_CHANNEL",
                      "MAKE_AN_APPOINTMENT",
                      "ASK_ABOUT_SERVICES",
                      "BOOK_A_CONSULTATION",
                      "GET_A_QUOTE",
                      "BUY_VIA_MESSAGE",
                      "ASK_FOR_MORE_INFO",
                      "VIEW_PRODUCT",
                      "VIEW_CHANNEL",
                      "WATCH_LIVE_VIDEO",
                      "JOIN_LIVE_VIDEO",
                      "IMAGINE",
                      "WATCH_NOW",
                      "STREAM_NOW",
                      "BUY_ACTIVITY_TICKETS",
                      "CALL",
                      "MISSED_CALL",
                      "CALL_NOW",
                      "CALL_ME",
                      "APPLY_NOW",
                      "BUY",
                      "GET_QUOTE",
                      "SUBSCRIBE",
                      "RECORD_NOW",
                      "VOTE_NOW",
                      "GIVE_FREE_RIDES",
                      "REGISTER_NOW",
                      "OPEN_MESSENGER_EXT",
                      "EVENT_RSVP",
                      "CIVIC_ACTION",
                      "SEND_INVITES",
                      "REFER_FRIENDS",
                      "REQUEST_TIME",
                      "SEE_MENU",
                      "SEARCH",
                      "TRY_IT",
                      "TRY_ON",
                      "LINK_CARD",
                      "DIAL_CODE",
                      "FIND_YOUR_GROUPS",
                      "START_ORDER",
                      "REGISTER",
                      "JOIN",
                      "ATTEND",
                      "REQUEST_DEMO",
                      "VIEW_QUOTE",
                      "APPLY"
                    ],
                    "type": "string"
                  },
                  "callouts": {
                    "description": "Google Search only. Short callout texts (max 25 chars each) that appear as non-clickable annotations under the ad, e.g. \"Free shipping\", \"24/7 support\".",
                    "items": {
                      "maxLength": 25,
                      "minLength": 1,
                      "type": "string"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  },
                  "campaignAttribution": {
                    "description": "Meta ad-set attribution. Required as SKADNETWORK for iOS 14+ app promotion or a SKAdNetwork campaign. Requires AUCTION buying. Standalone Meta ad-set creation is not supported; use this field on /apis/v1/ads/create.",
                    "enum": [
                      "AEM",
                      "SKADNETWORK"
                    ],
                    "type": "string"
                  },
                  "campaignName": {
                    "description": "Meta, Reddit and Google. Exact campaign name; overrides the default ` - Campaign`. Ignored when the request joins an existing campaign or ad set. Google: no line breaks and at most 255 characters, checked before calling Google.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "campaignNegativeKeywords": {
                    "description": "Google Search only; other platforms return 400. Campaign-level negative keywords (campaign_criterion.negative), created alongside the ad group. Editable later via PUT /apis/v1/ads/campaigns/{campaignId}/negative-keywords.",
                    "items": {
                      "description": "A Google Search keyword: a bare string (BROAD match), or an object naming the match type.",
                      "oneOf": [
                        {
                          "description": "Keyword text; defaults to BROAD match",
                          "maxLength": 80,
                          "minLength": 1,
                          "type": "string"
                        },
                        {
                          "properties": {
                            "matchType": {
                              "description": "Defaults to broad. Accepted in any case (EXACT, Exact) and stored lowercase.",
                              "enum": [
                                "exact",
                                "phrase",
                                "broad"
                              ],
                              "type": "string"
                            },
                            "text": {
                              "maxLength": 80,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "maxItems": 1000,
                    "type": "array"
                  },
                  "campaignStatus": {
                    "description": "Every platform. Sets the switch of the new campaign alone (LinkedIn: the campaign group) and overrides `status` for it. Omitted, it follows `status`. Ignored when the request creates no campaign (`existingCampaignId` or `adSetId`).",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "campaignType": {
                    "default": "display",
                    "description": "Google only. Performance Max requires assetGroup and Demand Gen requires demandGen; both are always created PAUSED. With `adSetId` it defaults to the ad group's own campaign type instead of display.",
                    "enum": [
                      "display",
                      "search",
                      "pmax",
                      "demand_gen"
                    ],
                    "type": "string"
                  },
                  "carouselCards": {
                    "description": "Carousel cards. Behavior per platform: Reddit: builds a carousel ad.",
                    "items": {
                      "properties": {
                        "callToAction": {
                          "description": "Card CTA override. Defaults to the top-level callToAction; same enum.",
                          "type": "string"
                        },
                        "description": {
                          "description": "Card description, shown under the headline.",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "headline": {
                          "description": "Card headline, shown below the card image.",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Card image; uploaded to the ad account and referenced by hash.",
                          "format": "uri",
                          "type": "string"
                        },
                        "linkUrl": {
                          "description": "Card destination URL. Defaults to the top-level linkUrl, or Meta's lead-form link when leadGenFormId is set and neither is provided.",
                          "format": "uri",
                          "type": "string"
                        }
                      },
                      "required": [
                        "imageUrl"
                      ],
                      "type": "object"
                    },
                    "maxItems": 10,
                    "minItems": 2,
                    "type": "array"
                  },
                  "catalogFormat": {
                    "description": "Meta catalog template creatives only (goal `catalog_sales`, goal `traffic` with `promotedObject.productSetId`, or `adSetId` with `promotedObject.productSetId`); a 400 otherwise. Omit it to let Meta pick the format.",
                    "enum": [
                      "single_image",
                      "carousel_images_multi_items",
                      "carousel_images_single_item",
                      "carousel_slideshows"
                    ],
                    "type": "string"
                  },
                  "cities": {
                    "description": "City-level geo targeting (Meta, Google and TikTok). An entry is `{ key }` or the key alone as a plain string (`[\"1006410\"]`).",
                    "items": {
                      "oneOf": [
                        {
                          "description": "The city id alone, e.g. \"1006410\" (same as { key: \"1006410\" }).",
                          "type": "string"
                        },
                        {
                          "properties": {
                            "distance_unit": {
                              "description": "Unit for radius. Required if radius is set.",
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "key": {
                              "description": "City id from /apis/v1/ads/targeting/search results (Meta city key, Google geo target constant id, TikTok location id).",
                              "type": "string"
                            },
                            "radius": {
                              "description": "Optional radius around the city. Must be set together with distance_unit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "countries": {
                    "description": "ISO 3166-1 alpha-2 country codes (e.g. ['NL']). Defaults to ['US'] when no other geo targeting (flat or nested `targeting`) is provided.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "countryGroups": {
                    "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it.",
                    "items": {
                      "enum": [
                        "africa",
                        "asia",
                        "europe",
                        "north_america",
                        "south_america",
                        "oceania",
                        "central_america",
                        "caribbean",
                        "eea",
                        "euro_area",
                        "nafta",
                        "mercosur",
                        "afta",
                        "apec",
                        "gcc",
                        "cisfta",
                        "emerging_markets",
                        "itunes_app_store",
                        "android_free_store",
                        "android_paid_store"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "creativeFeatures": {
                    "additionalProperties": {
                      "enum": [
                        "OPT_IN",
                        "OPT_OUT"
                      ],
                      "type": "string"
                    },
                    "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                    "type": "object"
                  },
                  "creatives": {
                    "description": "Meta-only. When present, switches to the multi-creative shape: creates 1 campaign + 1 ad set + N ads (one per entry here). Top-level `headline` / `body` / `imageUrl` / `linkUrl` / `callToAction` are ignored in this mode.",
                    "items": {
                      "description": "Each creative must supply EXACTLY ONE of `imageUrl` (image creative) or `video` (video creative).",
                      "properties": {
                        "body": {
                          "type": "string"
                        },
                        "callToAction": {
                          "enum": [
                            "BOOK_TRAVEL",
                            "CONTACT_US",
                            "DONATE",
                            "DONATE_NOW",
                            "DOWNLOAD",
                            "GET_DIRECTIONS",
                            "GO_LIVE",
                            "INTERESTED",
                            "LEARN_MORE",
                            "SEE_DETAILS",
                            "LIKE_PAGE",
                            "MESSAGE_PAGE",
                            "RAISE_MONEY",
                            "SAVE",
                            "SEND_TIP",
                            "SHOP_NOW",
                            "SIGN_UP",
                            "VIEW_INSTAGRAM_PROFILE",
                            "INSTAGRAM_MESSAGE",
                            "LOYALTY_LEARN_MORE",
                            "PURCHASE_GIFT_CARDS",
                            "PAY_TO_ACCESS",
                            "SEE_MORE",
                            "TRY_IN_CAMERA",
                            "WHATSAPP_LINK",
                            "GET_IN_TOUCH",
                            "TRY_NOW",
                            "ASK_A_QUESTION",
                            "START_A_CHAT",
                            "CHAT_NOW",
                            "ASK_US",
                            "CHAT_WITH_US",
                            "SHOP_ON_RETAILER",
                            "BOOK_NOW",
                            "CHECK_AVAILABILITY",
                            "ORDER_NOW",
                            "WHATSAPP_MESSAGE",
                            "GET_MOBILE_APP",
                            "INSTALL_MOBILE_APP",
                            "USE_MOBILE_APP",
                            "INSTALL_APP",
                            "USE_APP",
                            "PLAY_GAME",
                            "TRY_DEMO",
                            "WATCH_VIDEO",
                            "WATCH_MORE",
                            "OPEN_LINK",
                            "NO_BUTTON",
                            "LISTEN_MUSIC",
                            "MOBILE_DOWNLOAD",
                            "GET_OFFER",
                            "GET_OFFER_VIEW",
                            "BUY_NOW",
                            "BUY_TICKETS",
                            "UPDATE_APP",
                            "BET_NOW",
                            "ADD_TO_CART",
                            "SELL_NOW",
                            "GET_SHOWTIMES",
                            "LISTEN_NOW",
                            "GET_EVENT_TICKETS",
                            "REMIND_ME",
                            "SEARCH_MORE",
                            "PRE_REGISTER",
                            "SWIPE_UP_PRODUCT",
                            "SWIPE_UP_SHOP",
                            "PLAY_GAME_ON_FACEBOOK",
                            "VISIT_WORLD",
                            "OPEN_INSTANT_APP",
                            "JOIN_GROUP",
                            "GET_PROMOTIONS",
                            "SEND_UPDATES",
                            "INQUIRE_NOW",
                            "VISIT_PROFILE",
                            "CHAT_ON_WHATSAPP",
                            "EXPLORE_MORE",
                            "CONFIRM",
                            "JOIN_CHANNEL",
                            "MAKE_AN_APPOINTMENT",
                            "ASK_ABOUT_SERVICES",
                            "BOOK_A_CONSULTATION",
                            "GET_A_QUOTE",
                            "BUY_VIA_MESSAGE",
                            "ASK_FOR_MORE_INFO",
                            "VIEW_PRODUCT",
                            "VIEW_CHANNEL",
                            "WATCH_LIVE_VIDEO",
                            "JOIN_LIVE_VIDEO",
                            "IMAGINE",
                            "WATCH_NOW",
                            "STREAM_NOW",
                            "BUY_ACTIVITY_TICKETS",
                            "CALL",
                            "MISSED_CALL",
                            "CALL_NOW",
                            "CALL_ME",
                            "APPLY_NOW",
                            "BUY",
                            "GET_QUOTE",
                            "SUBSCRIBE",
                            "RECORD_NOW",
                            "VOTE_NOW",
                            "GIVE_FREE_RIDES",
                            "REGISTER_NOW",
                            "OPEN_MESSENGER_EXT",
                            "EVENT_RSVP",
                            "CIVIC_ACTION",
                            "SEND_INVITES",
                            "REFER_FRIENDS",
                            "REQUEST_TIME",
                            "SEE_MENU",
                            "SEARCH",
                            "TRY_IT",
                            "TRY_ON",
                            "LINK_CARD",
                            "DIAL_CODE",
                            "FIND_YOUR_GROUPS",
                            "START_ORDER"
                          ],
                          "type": "string"
                        },
                        "creativeFeatures": {
                          "additionalProperties": {
                            "enum": [
                              "OPT_IN",
                              "OPT_OUT"
                            ],
                            "type": "string"
                          },
                          "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                          "type": "object"
                        },
                        "description": {
                          "description": "Link description for this ad (link_data.description; video creatives: video_data.link_description). Falls back to the top-level `description`; when both are omitted Meta scrapes the destination URL's OG description.",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "headline": {
                          "maxLength": 255,
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Image creative. Mutually exclusive with `video`.",
                          "format": "uri",
                          "type": "string"
                        },
                        "linkUrl": {
                          "format": "uri",
                          "type": "string"
                        },
                        "name": {
                          "description": "Exact name for this ad. Falls back to ` #N` (N = 1-based position).",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "video": {
                          "description": "Video creative for this entry. Mutually exclusive with `imageUrl`.",
                          "properties": {
                            "thumbnailUrl": {
                              "format": "uri",
                              "type": "string"
                            },
                            "url": {
                              "format": "uri",
                              "type": "string"
                            }
                          },
                          "required": [
                            "url"
                          ],
                          "type": "object"
                        }
                      },
                      "required": [
                        "body",
                        "callToAction",
                        "headline",
                        "linkUrl"
                      ],
                      "type": "object"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "currency": {
                    "description": "ISO 4217 currency code matching the ad account's currency (e.g. `USD`). Meta only.",
                    "maxLength": 3,
                    "minLength": 3,
                    "type": "string"
                  },
                  "customLocations": {
                    "description": "Point-radius (lat/lng) geo targeting. Meta only (custom_locations). Rejected on platforms without radius support.",
                    "items": {
                      "properties": {
                        "address": {
                          "type": "string"
                        },
                        "distanceUnit": {
                          "enum": [
                            "mile",
                            "kilometer"
                          ],
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        },
                        "name": {
                          "type": "string"
                        },
                        "radius": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "distanceUnit",
                        "latitude",
                        "longitude",
                        "radius"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "defaultLocale": {
                    "description": "Meta only. Language the top-level copy is written in (e.g. `en`, `pt_BR`), used by the `translations` default rule. Defaults to `en`. Meta rejects a language asset feed whose default rule carries no locales of its own.",
                    "type": "string"
                  },
                  "demandGen": {
                    "additionalProperties": false,
                    "description": "Creative, channel and audience settings for a Google Demand Gen campaign (campaignType demand_gen).",
                    "properties": {
                      "adGroupName": {
                        "description": "Defaults to the ad name.",
                        "maxLength": 255,
                        "type": "string"
                      },
                      "audience": {
                        "additionalProperties": false,
                        "description": "Created as a Google Audience and attached to the ad group. Send at least one dimension. Ids are numeric Google ids (user lists, interest categories, custom audiences) from the same customer.",
                        "properties": {
                          "ageRanges": {
                            "items": {
                              "properties": {
                                "max": {
                                  "description": "Omit for no upper bound.",
                                  "enum": [
                                    24,
                                    34,
                                    44,
                                    54,
                                    64
                                  ],
                                  "type": "integer"
                                },
                                "min": {
                                  "enum": [
                                    18,
                                    25,
                                    35,
                                    45,
                                    55,
                                    65
                                  ],
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "min"
                              ],
                              "type": "object"
                            },
                            "maxItems": 6,
                            "minItems": 1,
                            "type": "array"
                          },
                          "customAudiences": {
                            "items": {
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "genders": {
                            "items": {
                              "enum": [
                                "male",
                                "female",
                                "undetermined"
                              ],
                              "type": "string"
                            },
                            "maxItems": 3,
                            "minItems": 1,
                            "type": "array"
                          },
                          "userInterests": {
                            "items": {
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "userLists": {
                            "items": {
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "audienceId": {
                        "description": "Attach an existing Google Audience by numeric id instead of audience. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "type": "string"
                      },
                      "businessName": {
                        "maxLength": 25,
                        "type": "string"
                      },
                      "callToAction": {
                        "description": "Image and carousel ads only. Call to action text such as 'Learn more'; Google picks one when omitted.",
                        "maxLength": 25,
                        "type": "string"
                      },
                      "carouselCards": {
                        "description": "Makes the ad a carousel ad. Each card needs its own image (no two cards may share one); use the same image shape on every card. Card images are uploaded to the account's asset library before the campaign is created, validateOnly included.",
                        "items": {
                          "additionalProperties": false,
                          "properties": {
                            "callToAction": {
                              "maxLength": 25,
                              "type": "string"
                            },
                            "finalUrl": {
                              "description": "Defaults to demandGen.finalUrl.",
                              "format": "uri",
                              "type": "string"
                            },
                            "headline": {
                              "maxLength": 40,
                              "type": "string"
                            },
                            "images": {
                              "additionalProperties": false,
                              "properties": {
                                "landscape": {
                                  "description": "1.91:1.",
                                  "format": "uri",
                                  "type": "string"
                                },
                                "portrait": {
                                  "description": "4:5.",
                                  "format": "uri",
                                  "type": "string"
                                },
                                "square": {
                                  "description": "1:1.",
                                  "format": "uri",
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            }
                          },
                          "required": [
                            "headline",
                            "images"
                          ],
                          "type": "object"
                        },
                        "maxItems": 10,
                        "minItems": 2,
                        "type": "array"
                      },
                      "channels": {
                        "description": "Channel controls on the new ad group. Only the listed channels serve; Google Maps, which this list cannot select, is turned off.",
                        "items": {
                          "enum": [
                            "youtube_in_stream",
                            "youtube_in_feed",
                            "youtube_shorts",
                            "discover",
                            "gmail",
                            "display"
                          ],
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "descriptions": {
                        "description": "A carousel ad takes exactly one.",
                        "items": {
                          "maxLength": 90,
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 1,
                        "type": "array"
                      },
                      "finalUrl": {
                        "format": "uri",
                        "type": "string"
                      },
                      "headlines": {
                        "description": "Distinct texts. A carousel ad takes exactly one.",
                        "items": {
                          "maxLength": 40,
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 1,
                        "type": "array"
                      },
                      "images": {
                        "additionalProperties": false,
                        "description": "Public image URLs. An image ad needs landscape or square; video and carousel ads take only one logo (carousel images go on each card).",
                        "properties": {
                          "landscape": {
                            "description": "1.91:1, at least 600x314.",
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "logo": {
                            "description": "1:1, at least 128x128.",
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "maxItems": 5,
                            "minItems": 1,
                            "type": "array"
                          },
                          "portrait": {
                            "description": "4:5, at least 480x600.",
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "square": {
                            "description": "1:1, at least 300x300.",
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          }
                        },
                        "required": [
                          "logo"
                        ],
                        "type": "object"
                      },
                      "longHeadlines": {
                        "description": "Video ads only, and required there.",
                        "items": {
                          "maxLength": 90,
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 1,
                        "type": "array"
                      },
                      "youtubeVideoIds": {
                        "description": "Makes the ad a video responsive ad.",
                        "items": {
                          "pattern": "^[A-Za-z0-9_-]{11}$",
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 1,
                        "type": "array"
                      }
                    },
                    "required": [
                      "businessName",
                      "descriptions",
                      "finalUrl",
                      "headlines",
                      "images"
                    ],
                    "type": "object"
                  },
                  "description": {
                    "description": "Meta only (facebook/instagram). Link description: the secondary text shown below the headline (Meta's link_data.description; on video creatives mapped to video_data.link_description).",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "descriptions": {
                    "description": "Meta only. Optional description variations for Multiple Text Options. Sent alongside `bodies` and `headlines`.",
                    "items": {
                      "maxLength": 255,
                      "type": "string"
                    },
                    "maxItems": 5,
                    "minItems": 1,
                    "type": "array"
                  },
                  "dsaBeneficiary": {
                    "description": "Legal entity that benefits from the ad. Required when targeting EU users (EU DSA, Article 26).",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "dsaPayor": {
                    "description": "Legal entity that pays for the ad. Can differ from `dsaBeneficiary` (for example, an agency paying for a client's ads). Same rules as `dsaBeneficiary`: required for EU targeting unless the ad account has a default payor.",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "dynamicCreative": {
                    "description": "Meta only. Dynamic Creative: supply a POOL of assets and Meta auto-combines and optimises them into the best-performing variations within a single ad (mapped to the creative's `asset_feed_spec`).",
                    "properties": {
                      "adFormat": {
                        "description": "Asset-feed ad format. Must match the pool: SINGLE_IMAGE / CAROUSEL_IMAGE require `imageUrls`, SINGLE_VIDEO requires `videoUrls` (400 otherwise). Defaults to SINGLE_IMAGE with `imageUrls`, SINGLE_VIDEO with `videoUrls`.",
                        "enum": [
                          "SINGLE_IMAGE",
                          "CAROUSEL_IMAGE",
                          "SINGLE_VIDEO"
                        ],
                        "type": "string"
                      },
                      "bodies": {
                        "description": "Primary-text variations (the body copy).",
                        "items": {
                          "type": "string"
                        },
                        "maxItems": 5,
                        "type": "array"
                      },
                      "callToActionTypes": {
                        "description": "CTA-button variations. Required.",
                        "items": {
                          "enum": [
                            "BOOK_TRAVEL",
                            "CONTACT_US",
                            "DONATE",
                            "DONATE_NOW",
                            "DOWNLOAD",
                            "GET_DIRECTIONS",
                            "GO_LIVE",
                            "INTERESTED",
                            "LEARN_MORE",
                            "SEE_DETAILS",
                            "LIKE_PAGE",
                            "MESSAGE_PAGE",
                            "RAISE_MONEY",
                            "SAVE",
                            "SEND_TIP",
                            "SHOP_NOW",
                            "SIGN_UP",
                            "VIEW_INSTAGRAM_PROFILE",
                            "INSTAGRAM_MESSAGE",
                            "LOYALTY_LEARN_MORE",
                            "PURCHASE_GIFT_CARDS",
                            "PAY_TO_ACCESS",
                            "SEE_MORE",
                            "TRY_IN_CAMERA",
                            "WHATSAPP_LINK",
                            "GET_IN_TOUCH",
                            "TRY_NOW",
                            "ASK_A_QUESTION",
                            "START_A_CHAT",
                            "CHAT_NOW",
                            "ASK_US",
                            "CHAT_WITH_US",
                            "SHOP_ON_RETAILER",
                            "BOOK_NOW",
                            "CHECK_AVAILABILITY",
                            "ORDER_NOW",
                            "WHATSAPP_MESSAGE",
                            "GET_MOBILE_APP",
                            "INSTALL_MOBILE_APP",
                            "USE_MOBILE_APP",
                            "INSTALL_APP",
                            "USE_APP",
                            "PLAY_GAME",
                            "TRY_DEMO",
                            "WATCH_VIDEO",
                            "WATCH_MORE",
                            "OPEN_LINK",
                            "NO_BUTTON",
                            "LISTEN_MUSIC",
                            "MOBILE_DOWNLOAD",
                            "GET_OFFER",
                            "GET_OFFER_VIEW",
                            "BUY_NOW",
                            "BUY_TICKETS",
                            "UPDATE_APP",
                            "BET_NOW",
                            "ADD_TO_CART",
                            "SELL_NOW",
                            "GET_SHOWTIMES",
                            "LISTEN_NOW",
                            "GET_EVENT_TICKETS",
                            "REMIND_ME",
                            "SEARCH_MORE",
                            "PRE_REGISTER",
                            "SWIPE_UP_PRODUCT",
                            "SWIPE_UP_SHOP",
                            "PLAY_GAME_ON_FACEBOOK",
                            "VISIT_WORLD",
                            "OPEN_INSTANT_APP",
                            "JOIN_GROUP",
                            "GET_PROMOTIONS",
                            "SEND_UPDATES",
                            "INQUIRE_NOW",
                            "VISIT_PROFILE",
                            "CHAT_ON_WHATSAPP",
                            "EXPLORE_MORE",
                            "CONFIRM",
                            "JOIN_CHANNEL",
                            "MAKE_AN_APPOINTMENT",
                            "ASK_ABOUT_SERVICES",
                            "BOOK_A_CONSULTATION",
                            "GET_A_QUOTE",
                            "BUY_VIA_MESSAGE",
                            "ASK_FOR_MORE_INFO",
                            "VIEW_PRODUCT",
                            "VIEW_CHANNEL",
                            "WATCH_LIVE_VIDEO",
                            "JOIN_LIVE_VIDEO",
                            "IMAGINE",
                            "WATCH_NOW",
                            "STREAM_NOW",
                            "BUY_ACTIVITY_TICKETS",
                            "CALL",
                            "MISSED_CALL",
                            "CALL_NOW",
                            "CALL_ME",
                            "APPLY_NOW",
                            "BUY",
                            "GET_QUOTE",
                            "SUBSCRIBE",
                            "RECORD_NOW",
                            "VOTE_NOW",
                            "GIVE_FREE_RIDES",
                            "REGISTER_NOW",
                            "OPEN_MESSENGER_EXT",
                            "EVENT_RSVP",
                            "CIVIC_ACTION",
                            "SEND_INVITES",
                            "REFER_FRIENDS",
                            "REQUEST_TIME",
                            "SEE_MENU",
                            "SEARCH",
                            "TRY_IT",
                            "TRY_ON",
                            "LINK_CARD",
                            "DIAL_CODE",
                            "FIND_YOUR_GROUPS",
                            "START_ORDER"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "descriptions": {
                        "description": "Description (link caption) variations.",
                        "items": {
                          "type": "string"
                        },
                        "maxItems": 5,
                        "type": "array"
                      },
                      "imageUrls": {
                        "description": "Pool of image URLs (1-10). Uploaded to the ad account and referenced by hash in the asset feed. Mutually exclusive with `videoUrls`.",
                        "items": {
                          "format": "uri",
                          "type": "string"
                        },
                        "maxItems": 10,
                        "minItems": 1,
                        "type": "array"
                      },
                      "linkUrls": {
                        "description": "Destination URL variations. At least one is required unless `goal` is `lead_generation`.",
                        "items": {
                          "format": "uri",
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "titles": {
                        "description": "Headline variations.",
                        "items": {
                          "type": "string"
                        },
                        "maxItems": 5,
                        "type": "array"
                      },
                      "videoUrls": {
                        "description": "Pool of video URLs (1-10). Uploaded to the ad account and referenced by video id in the asset feed. No thumbnails are needed: Meta auto-generates a poster per video. Mutually exclusive with `imageUrls`; `adFormat` defaults to SINGLE_VIDEO.",
                        "items": {
                          "format": "uri",
                          "type": "string"
                        },
                        "maxItems": 10,
                        "minItems": 1,
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "endDate": {
                    "description": "When the ad ends. If omitted: on a lifetime budget, the ad ends 7 days after it starts (reported in `appliedDefaults.endDate`); a daily budget runs until paused.",
                    "format": "date-time",
                    "type": "string"
                  },
                  "existingCampaignId": {
                    "description": "Create the new objects under this EXISTING campaign instead of creating a new one. Supported on Meta, Google Ads, LinkedIn, TikTok and Reddit Ads. Mutually exclusive with `adSetId` and `creatives[]`. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "existingCreativeId": {
                    "description": "Meta only. Reuse an EXISTING ad creative by id instead of building a new one from the copy/media fields (which are then ignored). Combine with `existingCampaignId` to build a multi-ad-set campaign that shares one creative.",
                    "type": "string"
                  },
                  "gender": {
                    "default": "all",
                    "description": "Restrict the audience by gender. 'male' targets men only, 'female' targets women only, 'all' (default) targets everyone. Applied on Meta, TikTok, Pinterest and Reddit. Ignored on Google, LinkedIn and X.",
                    "enum": [
                      "all",
                      "male",
                      "female"
                    ],
                    "type": "string"
                  },
                  "goal": {
                    "description": "The ad's goal. Available goals vary by platform. When omitted, it is inferred from the ad (see `appliedDefaults.goal` in the response); the attach shape inherits it from the ad set. Meta `conversions`: OUTCOME_SALES.",
                    "enum": [
                      "engagement",
                      "traffic",
                      "awareness",
                      "video_views",
                      "lead_generation",
                      "lead_conversion",
                      "conversions",
                      "app_promotion",
                      "catalog_sales",
                      "page_likes",
                      "page_visits",
                      "job_applicants"
                    ],
                    "type": "string"
                  },
                  "headline": {
                    "description": "Ad headline. Required for Meta, Google, Pinterest, LinkedIn, OpenAI Ads and Reddit Ads on legacy + attach shapes (for multi-creative, skip it and use `creatives[].headline`). Ignored for TikTok.",
                    "type": "string"
                  },
                  "headlines": {
                    "description": "Meta only. Headline variations for Multiple Text Options. Must be sent alongside `bodies`. The top-level `headline` field is used as the `object_story_spec.link_data.name` (`video_data.title` on a video creative).",
                    "items": {
                      "maxLength": 255,
                      "type": "string"
                    },
                    "maxItems": 5,
                    "minItems": 1,
                    "type": "array"
                  },
                  "identityId": {
                    "description": "TikTok: the identity the ad runs as, from GET /apis/v1/ads/tiktok-identities. Overrides the connected account's own identity; must be authorized on the advertiser.",
                    "type": "string"
                  },
                  "identityType": {
                    "description": "TikTok only. Forces the identity attribution on the ad: `TT_USER`: the posting account's open_id (real @username branding). Requires a connected TikTok posting account on the same profile.",
                    "enum": [
                      "TT_USER",
                      "CUSTOMIZED_USER",
                      "BC_AUTH_TT"
                    ],
                    "type": "string"
                  },
                  "imageUrl": {
                    "description": "Image creative for Meta/Google/Pinterest/LinkedIn on legacy + attach shapes. Mutually exclusive with `video`. LinkedIn: required unless `video` is set.",
                    "format": "uri",
                    "type": "string"
                  },
                  "images": {
                    "description": "Google Display (Responsive Display Ads) only. Google RDA requires both a landscape (1.91:1) and a square (1:1) marketing image; sending only one is rejected upstream as 'Too few.' (NOT_ENOUGH_*_MARKETING_IMAGE_ASSET). Supply both URLs here.",
                    "properties": {
                      "landscape": {
                        "description": "Landscape 1.91:1 marketing image URL (e.g. 1200x628). Also accepted via the top-level `imageUrl` for backward compatibility.",
                        "format": "uri",
                        "type": "string"
                      },
                      "square": {
                        "description": "Square 1:1 marketing image URL (e.g. 1080x1080). Required for Google Display.",
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "incomeTier": {
                    "description": "Normalized household-income tier. Meta and TikTok express all four; Google maps only `top_10`; rejected on LinkedIn, X, and Pinterest. On Meta, income targeting is incompatible with housing/employment/credit `specialAdCategories`.",
                    "enum": [
                      "top_5",
                      "top_10",
                      "top_10_25",
                      "top_25_50"
                    ],
                    "type": "string"
                  },
                  "instagramAccountId": {
                    "description": "Meta only. Overrides the Instagram account the ad is delivered as. Pass an Instagram Business Account ID (e.g. 17841...), mapped to the creative's `instagram_user_id`; it is sent as-is and never replaced.",
                    "type": "string"
                  },
                  "interests": {
                    "description": "Interest objects from /apis/v1/ads/targeting/search?dimension=interest (or dimension=interestKeyword on TikTok). Each must include id and name. TikTok: Bare numeric ids are interest categories (`interest_category_ids`).",
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "name"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "isSkadnetworkAttribution": {
                    "description": "Meta app promotion only. Immutable campaign flag. Set true for iOS 14+ SKAdNetwork campaigns and supply promotedObject.applicationId plus promotedObject.objectStoreUrl. The campaign receives promotedObject only when this flag is true.",
                    "type": "boolean"
                  },
                  "keywords": {
                    "description": "Google Search only. Keywords on the new ad group; entries are strings (BROAD) or { text, matchType }. Editable later via PUT /apis/v1/ads/{adId} targeting.keywords.",
                    "items": {
                      "description": "A Google Search keyword: a bare string (BROAD match), or an object naming the match type.",
                      "oneOf": [
                        {
                          "description": "Keyword text; defaults to BROAD match",
                          "maxLength": 80,
                          "minLength": 1,
                          "type": "string"
                        },
                        {
                          "properties": {
                            "matchType": {
                              "description": "Defaults to broad. Accepted in any case (EXACT, Exact) and stored lowercase.",
                              "enum": [
                                "exact",
                                "phrase",
                                "broad"
                              ],
                              "type": "string"
                            },
                            "text": {
                              "maxLength": 80,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "maxItems": 1000,
                    "type": "array"
                  },
                  "languages": {
                    "description": "Language codes, e.g. [\"en\",\"es\"]. Google: campaign language targeting (language_constant) using Google's language codes (ISO 639-1, plus variants such as `zh_CN`). Unknown codes return 400.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "leadGenFormId": {
                    "description": "Lead Gen form ID to attach to the ad's creative. REQUIRED when `goal` is `lead_generation`. Create one via POST /apis/v1/ads/lead-forms. Meta (facebook/instagram): the leadgen_forms ID.",
                    "type": "string"
                  },
                  "linkUrl": {
                    "description": "The ad's destination URL. Required on legacy + attach shapes (skip for multi-creative). NOT required when `goal` is `lead_generation` (the ad opens a Lead Gen form instead).",
                    "format": "uri",
                    "type": "string"
                  },
                  "locationTargetingType": {
                    "description": "Google only (400 elsewhere). Set on the new campaign; a request that joins an existing campaign (`existingCampaignId` or `adSetId`) returns 400, change that campaign with PUT /apis/v1/ads/campaigns/{campaignId}/targeting instead.",
                    "enum": [
                      "presence",
                      "presence_or_interest"
                    ],
                    "type": "string"
                  },
                  "longHeadline": {
                    "description": "Google Display only. Defaults to `headline` if omitted. On LinkedIn, reused as the optional secondary description text on traffic (link) ads; omitted if not provided.",
                    "maxLength": 90,
                    "type": "string"
                  },
                  "manualCpc": {
                    "additionalProperties": false,
                    "description": "Google Search and Display only. Manual CPC bidding. Enhanced CPC is not offered: Google no longer lets Search and Display campaigns enable it. Exclusive with every other strategy field.",
                    "properties": {
                      "maxCpc": {
                        "description": "Max CPC of the ad groups, in the account's currency units: set on the ad group created with the campaign, and on every ad group of the campaign when an update switches it to Manual CPC. Google gives an ad group without one a 0.01 bid.",
                        "exclusiveMinimum": 0,
                        "type": "number"
                      }
                    },
                    "required": [
                      "maxCpc"
                    ],
                    "type": "object"
                  },
                  "metros": {
                    "description": "DMA / metro-area geo targeting (Meta and TikTok). `key` is the platform's metro ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=metro (TikTok metros appear as type `metro`, e.g. the New York DMA).",
                    "items": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "type": "array"
                  },
                  "multiAdvertiser": {
                    "description": "Meta only. Multi-advertiser ads: whether Meta may show this ad alongside other advertisers' in one unit. Meta auto-enrols since Aug 2024, so send OPT_OUT to leave.",
                    "enum": [
                      "OPT_IN",
                      "OPT_OUT"
                    ],
                    "type": "string"
                  },
                  "name": {
                    "description": "Omitted, the ad is named `Ad ` (UTC) and the response reports it in `appliedDefaults.name`.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "negativeKeywords": {
                    "description": "Google Search only; other platforms return 400. Ad-group-level negative keywords on the new ad group. Editable later via PUT /apis/v1/ads/{adId} targeting.negativeKeywords.",
                    "items": {
                      "description": "A Google Search keyword: a bare string (BROAD match), or an object naming the match type.",
                      "oneOf": [
                        {
                          "description": "Keyword text; defaults to BROAD match",
                          "maxLength": 80,
                          "minLength": 1,
                          "type": "string"
                        },
                        {
                          "properties": {
                            "matchType": {
                              "description": "Defaults to broad. Accepted in any case (EXACT, Exact) and stored lowercase.",
                              "enum": [
                                "exact",
                                "phrase",
                                "broad"
                              ],
                              "type": "string"
                            },
                            "text": {
                              "maxLength": 80,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "maxItems": 1000,
                    "type": "array"
                  },
                  "networkSettings": {
                    "additionalProperties": false,
                    "description": "Google Search only, when the call creates the campaign (400 with existingCampaignId or adSetId).",
                    "properties": {
                      "displayNetwork": {
                        "description": "campaign.network_settings.target_content_network (Search with Display expansion)",
                        "type": "boolean"
                      },
                      "searchPartners": {
                        "description": "campaign.network_settings.target_search_network",
                        "type": "boolean"
                      }
                    },
                    "type": "object"
                  },
                  "optimizationGoal": {
                    "description": "Explicit optimization goal. Supported on: TikTok with goal video_views: ENGAGED_VIEW (the 6-second default) or ENGAGED_VIEW_FIFTEEN; both bill per view.",
                    "type": "string"
                  },
                  "optimizeCardOrder": {
                    "description": "Meta only (a 400 on any other platform), and only with `carouselCards` (a 400 without them). Sets the creative's `link_data.multi_share_optimized`. `false`: keeps the cards in the order given.",
                    "type": "boolean"
                  },
                  "organizationId": {
                    "description": "LinkedIn only (ignored by every other platform). The Company Page that authors the Direct Sponsored Content (\"dark\") post backing the ad. Accepts a numeric organization ID or a full `urn:li:organization:N` URN. Required unless it defaults:",
                    "type": "string"
                  },
                  "pageId": {
                    "description": "Meta only. The Facebook Page the ad runs as (`object_story_spec.page_id`). Defaults to the Page bound to the connection. Pass another Page ID to run the ad as that Page.",
                    "type": "string"
                  },
                  "phoneNumber": {
                    "description": "Meta attach shape only (`adSetId`). The phone number (E.164, e.g. `+4712345678`) for an ad added to a \"website and phone call\" ad set (destination_type `WEBSITE_AND_PHONE_CALL`), sent as the creative's call configuration.",
                    "pattern": "^\\+[1-9]\\d{6,14}$",
                    "type": "string"
                  },
                  "placementAssets": {
                    "description": "Meta only. Pins a SPECIFIC asset (image OR video) to each placement group on a SINGLE ad (e.g. a 9:16 on Stories/Reels and a 4:5 on Feed).",
                    "properties": {
                      "defaultImageUrl": {
                        "description": "Image mode. Catch-all image for any placement no rule matches. Required in image mode (Meta mandates a default rule).",
                        "format": "uri",
                        "type": "string"
                      },
                      "defaultThumbnailUrl": {
                        "description": "Video mode (optional). Poster image for the default video; Meta auto-generates one when omitted.",
                        "format": "uri",
                        "type": "string"
                      },
                      "defaultVideoUrl": {
                        "description": "Video mode. Catch-all video for any placement no rule matches. Required in video mode.",
                        "format": "uri",
                        "type": "string"
                      },
                      "rules": {
                        "description": "One entry per placement group you want to pin a specific asset to.",
                        "items": {
                          "properties": {
                            "body": {
                              "description": "One primary text pinned to this rule. Omit to inherit the top-level body.",
                              "minLength": 1,
                              "type": "string"
                            },
                            "description": {
                              "description": "One link description pinned to this rule. Omit to inherit the top-level description.",
                              "maxLength": 255,
                              "minLength": 1,
                              "type": "string"
                            },
                            "headline": {
                              "description": "One headline pinned to this rule. Omit to inherit the top-level headline.",
                              "maxLength": 255,
                              "minLength": 1,
                              "type": "string"
                            },
                            "imageUrl": {
                              "description": "Image mode. The image to deliver for this rule's placements.",
                              "format": "uri",
                              "type": "string"
                            },
                            "placements": {
                              "description": "Placements this asset is pinned to. At least one field must be set (an empty rule is invalid; that role is served by the default asset). Same enums as the top-level `placements` object.",
                              "properties": {
                                "audienceNetworkPositions": {
                                  "items": {
                                    "enum": [
                                      "classic",
                                      "rewarded_video"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "devicePlatforms": {
                                  "items": {
                                    "enum": [
                                      "mobile",
                                      "desktop"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "facebookPositions": {
                                  "items": {
                                    "enum": [
                                      "feed",
                                      "right_hand_column",
                                      "marketplace",
                                      "story",
                                      "search",
                                      "instream_video",
                                      "facebook_reels",
                                      "facebook_reels_overlay",
                                      "profile_feed",
                                      "notification"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "instagramPositions": {
                                  "items": {
                                    "enum": [
                                      "stream",
                                      "story",
                                      "explore",
                                      "explore_home",
                                      "reels",
                                      "profile_feed",
                                      "ig_search",
                                      "profile_reels"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "messengerPositions": {
                                  "items": {
                                    "enum": [
                                      "messenger_home",
                                      "sponsored_messages",
                                      "story"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "publisherPlatforms": {
                                  "items": {
                                    "enum": [
                                      "facebook",
                                      "instagram",
                                      "threads",
                                      "messenger",
                                      "audience_network",
                                      "whatsapp",
                                      "meta"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "threadsPositions": {
                                  "items": {
                                    "enum": [
                                      "threads_stream"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "whatsappPositions": {
                                  "items": {
                                    "enum": [
                                      "status"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "thumbnailUrl": {
                              "description": "Video mode (optional). Poster image for this rule's video; auto-generated when omitted.",
                              "format": "uri",
                              "type": "string"
                            },
                            "videoUrl": {
                              "description": "Video mode. The video to deliver for this rule's placements.",
                              "format": "uri",
                              "type": "string"
                            }
                          },
                          "required": [
                            "placements"
                          ],
                          "type": "object"
                        },
                        "maxItems": 10,
                        "minItems": 1,
                        "type": "array"
                      }
                    },
                    "required": [
                      "rules"
                    ],
                    "type": "object"
                  },
                  "placements": {
                    "description": "Meta only; non-Meta platforms reject this field. Manual ad placements. Omit for automatic placements (Meta's default, recommended for most cases, since Meta optimises delivery across all eligible surfaces).",
                    "properties": {
                      "audienceNetworkPositions": {
                        "items": {
                          "enum": [
                            "classic",
                            "rewarded_video"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "devicePlatforms": {
                        "description": "Restrict by device. Omit to deliver on both mobile and desktop.",
                        "items": {
                          "enum": [
                            "mobile",
                            "desktop"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "facebookPositions": {
                        "items": {
                          "enum": [
                            "feed",
                            "right_hand_column",
                            "marketplace",
                            "story",
                            "search",
                            "instream_video",
                            "facebook_reels",
                            "facebook_reels_overlay",
                            "profile_feed",
                            "notification"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "instagramPositions": {
                        "items": {
                          "enum": [
                            "stream",
                            "story",
                            "explore",
                            "explore_home",
                            "reels",
                            "profile_feed",
                            "ig_search",
                            "profile_reels"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "messengerPositions": {
                        "items": {
                          "enum": [
                            "messenger_home",
                            "sponsored_messages",
                            "story"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "publisherPlatforms": {
                        "description": "Top-level platforms to deliver on. A position field below is only honoured when its parent platform is included here.",
                        "items": {
                          "enum": [
                            "facebook",
                            "instagram",
                            "threads",
                            "messenger",
                            "audience_network",
                            "whatsapp",
                            "meta"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "threadsPositions": {
                        "items": {
                          "enum": [
                            "threads_stream"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "whatsappPositions": {
                        "items": {
                          "enum": [
                            "status"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "platformSpecificData": {
                    "description": "Platform-specific options. The platform is derived from `connectionId`; options for a different platform return a 400. LinkedIn (campaign bidding and delivery controls) and Meta (the bid trio) have options today. Meta",
                    "oneOf": [
                      {
                        "additionalProperties": false,
                        "description": "LinkedIn-specific options for POST /apis/v1/ads/boost and POST /apis/v1/ads/create: campaign bidding and delivery controls, plus the LinkedIn-only creative formats on /apis/v1/ads/create. Unknown keys are rejected.",
                        "properties": {
                          "audienceExpansionEnabled": {
                            "description": "Enable LinkedIn audience expansion. Defaults to false.",
                            "type": "boolean"
                          },
                          "carousel": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Carousel ad with 2-10 image cards. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "cards": {
                                "items": {
                                  "additionalProperties": false,
                                  "properties": {
                                    "headline": {
                                      "description": "Card title. Falls back to the ad-level headline.",
                                      "type": "string"
                                    },
                                    "imageUrl": {
                                      "format": "uri",
                                      "type": "string"
                                    },
                                    "landingUrl": {
                                      "description": "Per-card click destination. LinkedIn requires one on every card; the ad-level `linkUrl` backfills cards that omit it.",
                                      "format": "uri",
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "imageUrl"
                                  ],
                                  "type": "object"
                                },
                                "maxItems": 10,
                                "minItems": 2,
                                "type": "array"
                              }
                            },
                            "required": [
                              "cards"
                            ],
                            "type": "object"
                          },
                          "connectedTelevisionOnly": {
                            "description": "Restrict delivery to Connected TV inventory.",
                            "type": "boolean"
                          },
                          "conversation": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Conversation Ad: a choose-your-path message tree delivered to the member's LinkedIn inbox. Messages are flat nodes wired by local ids. Each button either opens a url or leads to nextMessageId.",
                            "properties": {
                              "body": {
                                "description": "Optional intro body (HTML allowed).",
                                "type": "string"
                              },
                              "firstMessageId": {
                                "type": "string"
                              },
                              "footer": {
                                "description": "Terms shown at the bottom of the message.",
                                "type": "string"
                              },
                              "headline": {
                                "description": "Conversation headline. Defaults to the first message's first line.",
                                "type": "string"
                              },
                              "messages": {
                                "items": {
                                  "additionalProperties": false,
                                  "properties": {
                                    "buttons": {
                                      "items": {
                                        "additionalProperties": true,
                                        "type": "object"
                                      },
                                      "maxItems": 5,
                                      "minItems": 1,
                                      "type": "array"
                                    },
                                    "id": {
                                      "type": "string"
                                    },
                                    "text": {
                                      "maxLength": 500,
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "text"
                                  ],
                                  "type": "object"
                                },
                                "maxItems": 25,
                                "minItems": 1,
                                "type": "array"
                              },
                              "sender": {
                                "description": "Person or organization URN. Defaults to the authoring Company Page. The sender must be approved for the ad account first (Campaign Manager > Manage message ad senders) or LinkedIn rejects the create with SINMAIL_SENDER_NOT_APPROVED.",
                                "type": "string"
                              },
                              "subject": {
                                "description": "InMail subject shown in the inbox.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "firstMessageId",
                              "messages",
                              "subject"
                            ],
                            "type": "object"
                          },
                          "costType": {
                            "description": "Campaign cost model (billing event). Defaults to `CPM`. Required when `unitCost` is set so the manual bid applies to an explicit cost model.",
                            "enum": [
                              "CPM",
                              "CPC",
                              "CPV"
                            ],
                            "type": "string"
                          },
                          "creativeSelection": {
                            "description": "How LinkedIn rotates creatives within the campaign. Defaults to `OPTIMIZED`.",
                            "enum": [
                              "OPTIMIZED",
                              "ROUND_ROBIN"
                            ],
                            "type": "string"
                          },
                          "document": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Document ad rendered as an in-feed viewer. PDF, PPT or DOC up to 100MB. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "title": {
                                "description": "Document title.",
                                "type": "string"
                              },
                              "url": {
                                "format": "uri",
                                "type": "string"
                              }
                            },
                            "required": [
                              "title",
                              "url"
                            ],
                            "type": "object"
                          },
                          "event": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Promotes an existing LinkedIn Event; no headline needed. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "urn": {
                                "description": "LinkedIn Event URN, urn:li:event:N.",
                                "pattern": "^urn:li:event:\\d+$",
                                "type": "string"
                              }
                            },
                            "required": [
                              "urn"
                            ],
                            "type": "object"
                          },
                          "follower": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Dynamic Follower Ad promoting the Company Page. Supported goals: engagement, awareness. headline and description take exactly one of preApproved or custom. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "callToAction": {
                                "enum": [
                                  "VISIT_ORGANIZATION_COMPANY_PAGE",
                                  "VISIT_ORGANIZATION_LIFE_PAGE",
                                  "VISIT_ORGANIZATION_JOBS_PAGE",
                                  "VISIT_ORGANIZATION_CAREERS_PAGE"
                                ],
                                "type": "string"
                              },
                              "description": {
                                "additionalProperties": false,
                                "properties": {
                                  "custom": {
                                    "description": "Free text, reviewed by LinkedIn.",
                                    "type": "string"
                                  },
                                  "preApproved": {
                                    "description": "LinkedIn preset id, not reviewed. Example GET_LATEST_JOBS_AND_INDUSTRY_NEWS.",
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "headline": {
                                "additionalProperties": false,
                                "properties": {
                                  "custom": {
                                    "description": "Free text, reviewed by LinkedIn.",
                                    "type": "string"
                                  },
                                  "preApproved": {
                                    "description": "LinkedIn preset id, not reviewed. Example GROW_YOUR_BUSINESS_INSIGHTS.",
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "logoUrl": {
                                "format": "uri",
                                "type": "string"
                              },
                              "organizationName": {
                                "type": "string"
                              },
                              "showMemberProfilePhoto": {
                                "description": "Defaults to true.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "callToAction",
                              "description",
                              "headline"
                            ],
                            "type": "object"
                          },
                          "jobs": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Dynamic Jobs Ad promoting your open roles, personalized with the viewer's profile photo. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "buttonLabel": {
                                "additionalProperties": false,
                                "properties": {
                                  "custom": {
                                    "description": "Free text, reviewed by LinkedIn.",
                                    "type": "string"
                                  },
                                  "preApproved": {
                                    "description": "LinkedIn preset id, not reviewed. One of SEE_MORE_JOBS, VIEW_MORE, CAREERS_AT_COMPANY.",
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "headline": {
                                "additionalProperties": false,
                                "properties": {
                                  "custom": {
                                    "description": "Free text, reviewed by LinkedIn.",
                                    "type": "string"
                                  },
                                  "preApproved": {
                                    "description": "LinkedIn preset id, not reviewed. Example MEMBER_READY_FOR_YOUR_DREAM_JOB.",
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "logoUrl": {
                                "format": "uri",
                                "type": "string"
                              },
                              "organizationName": {
                                "type": "string"
                              },
                              "showMemberProfilePhoto": {
                                "description": "Defaults to true.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "buttonLabel",
                              "headline"
                            ],
                            "type": "object"
                          },
                          "offsiteDeliveryEnabled": {
                            "description": "Deliver on the LinkedIn Audience Network. Defaults to false.",
                            "type": "boolean"
                          },
                          "optimizationTargetType": {
                            "description": "Campaign `optimizationTargetType` (e.g. `MAX_CLICK`, `TARGET_COST_PER_CLICK`, `MAX_IMPRESSION`). Forwarded verbatim; LinkedIn validates compatibility with the objective and `costType`. Default when omitted, derived from the objective:",
                            "type": "string"
                          },
                          "spotlight": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Dynamic Spotlight Ad personalized with the viewer's profile photo. Supported goals: traffic, awareness.",
                            "properties": {
                              "backgroundImageUrl": {
                                "description": "Custom background. Replaces the description and the profile photo.",
                                "format": "uri",
                                "type": "string"
                              },
                              "callToAction": {
                                "description": "Button label text.",
                                "type": "string"
                              },
                              "description": {
                                "description": "Mutually exclusive with backgroundImageUrl.",
                                "type": "string"
                              },
                              "headline": {
                                "type": "string"
                              },
                              "landingUrl": {
                                "format": "uri",
                                "type": "string"
                              },
                              "logoUrl": {
                                "format": "uri",
                                "type": "string"
                              },
                              "organizationName": {
                                "type": "string"
                              },
                              "showMemberProfilePhoto": {
                                "description": "Defaults to true.",
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "callToAction",
                              "headline",
                              "landingUrl"
                            ],
                            "type": "object"
                          },
                          "textAd": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Classic right-rail Text Ad. The copy lives here; ad-level body and headline are not used. Mutually exclusive with the other creative sources.",
                            "properties": {
                              "description": {
                                "maxLength": 75,
                                "type": "string"
                              },
                              "headline": {
                                "maxLength": 25,
                                "type": "string"
                              },
                              "imageUrl": {
                                "description": "Optional 100x100 image.",
                                "format": "uri",
                                "type": "string"
                              },
                              "landingUrl": {
                                "format": "uri",
                                "type": "string"
                              }
                            },
                            "required": [
                              "description",
                              "headline",
                              "landingUrl"
                            ],
                            "type": "object"
                          },
                          "thoughtLeader": {
                            "additionalProperties": false,
                            "description": "POST /apis/v1/ads/create only. Sponsors an existing LinkedIn post (a share or ugcPost authored by your organization's Company Page) as the creative, keeping its commentary, author and engagement.",
                            "properties": {
                              "postUrn": {
                                "description": "LinkedIn share or ugcPost URN: urn:li:share:N or urn:li:ugcPost:N. Get it via \"Copy link to post\" on the target LinkedIn post. The URL contains -share- (share) or -ugcPost- (ugcPost), then the numeric id.",
                                "pattern": "^urn:li:(share|ugcPost):\\d+$",
                                "type": "string"
                              }
                            },
                            "required": [
                              "postUrn"
                            ],
                            "type": "object"
                          },
                          "unitCost": {
                            "description": "Manual bid in WHOLE account-currency units (e.g. 2.5 = $2.50). Requires `costType`. Omit for LinkedIn's automated (max delivery) bidding. LinkedIn enforces its own per-audience min/max bid bounds.",
                            "type": "number"
                          }
                        },
                        "type": "object"
                      },
                      {
                        "additionalProperties": false,
                        "description": "Meta (facebook/instagram) options for platformSpecificData on POST /apis/v1/ads/boost and /apis/v1/ads/create. Unknown keys are rejected, not dropped.",
                        "properties": {
                          "adSchedule": {
                            "description": "Dayparting on the ad set being created (Meta `adset_schedule` with `pacing_type: [\"day_parting\"]`). Change it later with `PUT /apis/v1/ads/ad-sets/{adSetId}`. A 400 with `param: platformSpecificData.adSchedule` when:",
                            "items": {
                              "additionalProperties": false,
                              "properties": {
                                "dayOfWeek": {
                                  "enum": [
                                    "MONDAY",
                                    "TUESDAY",
                                    "WEDNESDAY",
                                    "THURSDAY",
                                    "FRIDAY",
                                    "SATURDAY",
                                    "SUNDAY"
                                  ],
                                  "type": "string"
                                },
                                "endHour": {
                                  "description": "Must be after startHour. 24 is midnight at the end of the day.",
                                  "maximum": 24,
                                  "minimum": 1,
                                  "type": "integer"
                                },
                                "startHour": {
                                  "maximum": 23,
                                  "minimum": 0,
                                  "type": "integer"
                                },
                                "timezoneType": {
                                  "default": "USER",
                                  "description": "Meta `timezone_type`: USER runs the hours in each viewer's time zone, ADVERTISER in the ad account time zone.",
                                  "enum": [
                                    "USER",
                                    "ADVERTISER"
                                  ],
                                  "type": "string"
                                }
                              },
                              "required": [
                                "dayOfWeek",
                                "endHour",
                                "startHour"
                              ],
                              "type": "object"
                            },
                            "maxItems": 168,
                            "minItems": 1,
                            "type": "array"
                          },
                          "bidAmount": {
                            "description": "Whole currency units (USD: 5 = $5.00). Required when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP.",
                            "type": "number"
                          },
                          "bidStrategy": {
                            "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                            "enum": [
                              "LOWEST_COST_WITHOUT_CAP",
                              "LOWEST_COST_WITH_BID_CAP",
                              "COST_CAP",
                              "LOWEST_COST_WITH_MIN_ROAS"
                            ],
                            "type": "string"
                          },
                          "customerLifecycle": {
                            "additionalProperties": false,
                            "description": "Meta's Customer Lifecycle Strategy on a Sales ad set (Meta `ad_set_goal`). Rejected with 400 in adSetId attach mode: use PUT /apis/v1/ads/ad-sets/{adSetId} for an ad set that already exists.",
                            "properties": {
                              "engagedAudienceIds": {
                                "description": "Custom audience ids of people who engaged but have not bought. Required with new_customers_excluding_engaged, not allowed with the other strategies. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "existingCustomerAudienceIds": {
                                "description": "Custom audience ids that define your existing customers. Required with both new_customers strategies (Meta answers 400 subcode 1870251 without them); not allowed with all_customers. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "strategy": {
                                "description": "`all_customers` is \"Maximize conversions from all customers\". `new_customers` is \"Acquire new customers\" (excludes existing customers). `new_customers_excluding_engaged` also excludes people who engaged with you but have not bought yet.",
                                "enum": [
                                  "all_customers",
                                  "new_customers",
                                  "new_customers_excluding_engaged"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "strategy"
                            ],
                            "type": "object"
                          },
                          "dailyMinSpendTarget": {
                            "description": "Meta daily_min_spend_target on the ad set being created: the least it should spend per day, in whole currency units. A target, not a guarantee.",
                            "type": "number"
                          },
                          "lifetimeMinSpendTarget": {
                            "description": "Meta lifetime_min_spend_target: the lifetime-budget flavour of dailyMinSpendTarget, in whole currency units. Same rules and same rejections.",
                            "type": "number"
                          },
                          "roasAverageFloor": {
                            "description": "Decimal ROAS multiplier (2.0 = 2.0x). Required when bidStrategy is LOWEST_COST_WITH_MIN_ROAS; sending it without bidStrategy is a 400.",
                            "type": "number"
                          }
                        },
                        "type": "object"
                      }
                    ]
                  },
                  "portfolioBidStrategyId": {
                    "description": "Google Search and Display only. Performance Max rejects portfolio bidding. Attach an existing portfolio bid strategy (numeric id from GET /apis/v1/ads/bid-strategies) to the new campaign instead of a standard one.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "promotedObject": {
                    "additionalProperties": false,
                    "description": "What the ad optimises against. Behaviour depends on the platform. Platforms other than Meta, TikTok, OpenAI and Reddit ignore `promotedObject` entirely. Meta: forwarded to the ad set's `promoted_object` (snake-cased).",
                    "properties": {
                      "applicationId": {
                        "description": "App ID. Required for `goal: app_promotion`.",
                        "type": "string"
                      },
                      "customConversionId": {
                        "description": "Custom Conversion ID, when optimising against one instead of a standard event. Accepted alone by this API, without `pixelId` or `customEventType`.",
                        "type": "string"
                      },
                      "customEventStr": {
                        "description": "Meta only. Pixel custom-event name to optimise against (Meta's `custom_event_str`), exactly as it appears in Events Manager and your CAPI payloads (case-sensitive, not uppercased).",
                        "type": "string"
                      },
                      "customEventType": {
                        "description": "The event the campaign/ad group optimises against. Meta: a standard event like `PURCHASE`, `LEAD`, `COMPLETE_REGISTRATION`, `ADD_TO_CART`. Uppercased internally, so any case works. Required for `goal: conversions`.",
                        "type": "string"
                      },
                      "objectStoreUrl": {
                        "description": "App Store / Play Store listing URL. Required for `goal: app_promotion`.",
                        "format": "uri",
                        "type": "string"
                      },
                      "offlineConversionDataSetId": {
                        "description": "Meta only. Offline event set (dataset) to optimise toward. Post-merger these are datasets: the id is the dataset id (for pixel-backed datasets, the pixel id).",
                        "type": "string"
                      },
                      "pageId": {
                        "description": "Facebook Page ID. Used by `goal: lead_generation`. Auto-filled from the connected Page when omitted.",
                        "type": "string"
                      },
                      "pixelId": {
                        "description": "Pixel ID. Meta: Facebook Pixel ID, required for `goal: conversions`.",
                        "type": "string"
                      },
                      "productCatalogId": {
                        "description": "Optional catalog ID. A catalog ID cannot replace productSetId.",
                        "type": "string"
                      },
                      "productSetId": {
                        "description": "Meta product SET ID, for example from GET /apis/v1/ads/catalogs/{catalogId}/product-sets. Creating catalog ads needs only ads_management on the Meta login, not catalog_management. Where it goes.",
                        "type": "string"
                      },
                      "whatsappPhoneNumber": {
                        "description": "Meta only. WhatsApp number on messaging-destination ad sets.",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "promotion": {
                    "description": "Not supported. Send null or omit the field, and set the Promotion on the ad in Ads Manager. Any object is rejected with 400 invalid_field_value.",
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "rawTargeting": {
                    "additionalProperties": true,
                    "description": "Meta only.",
                    "type": "object"
                  },
                  "regionalRegulatedCategories": {
                    "description": "Meta only. Regional regulation categories required when the ad set targets certain countries.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "regionalRegulationIdentities": {
                    "additionalProperties": {
                      "type": [
                        "string",
                        "integer"
                      ]
                    },
                    "description": "Meta only. Verified identity IDs of the beneficiary and payer for each declared regionalRegulatedCategories value. Ignored when adSetId adds the ad to an existing ad set.",
                    "type": "object"
                  },
                  "regions": {
                    "description": "Region-level (state/province) geo targeting (Meta, Google and TikTok). Each region is targeted by the platform's opaque `key` (the region ID) which can be looked up via `GET /apis/v1/ads/targeting/search?dimension=geo&q=&countryCode=`.",
                    "items": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "properties": {
                            "key": {
                              "description": "Platform region ID, from /apis/v1/ads/targeting/search results.",
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "type": "array"
                  },
                  "rfPredictionId": {
                    "description": "Meta only. The RESERVED prediction id the R&F ad set runs on (reserving mints a new id, so pass that one). Requires buyingType RESERVED.",
                    "type": "string"
                  },
                  "roasAverageFloor": {
                    "description": "Deprecated: send it inside `platformSpecificData` instead (Meta today; TikTok's nested shape is planned). The flat field keeps working during the deprecation window. Sending both shapes returns a 400.",
                    "type": "number"
                  },
                  "savedTargetingId": {
                    "description": "ID of a `saved_targeting` audience (created via POST /apis/v1/ads/audiences). When set, its stored TargetingSpec is expanded as the base targeting; inline fields on this body merge on top. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "sitelinks": {
                    "description": "Google Search only. Sitelink assets to create and attach at the campaign level. Each entry becomes an Asset (with sitelink_asset + Asset.final_urls) plus a CampaignAsset link (field_type SITELINK).",
                    "items": {
                      "properties": {
                        "description1": {
                          "description": "First description line under the link text (optional). 35-char cap.",
                          "maxLength": 35,
                          "minLength": 1,
                          "type": "string"
                        },
                        "description2": {
                          "description": "Second description line (optional; usually paired with description1).",
                          "maxLength": 35,
                          "minLength": 1,
                          "type": "string"
                        },
                        "linkUrl": {
                          "description": "Final URL the sitelink navigates to.",
                          "format": "uri",
                          "type": "string"
                        },
                        "text": {
                          "description": "The clickable link text shown under the ad. 25-char cap comes from Google.",
                          "maxLength": 25,
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "linkUrl",
                        "text"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 2,
                    "type": "array"
                  },
                  "smartPlus": {
                    "description": "TikTok only. Creates the ad as a TikTok Upgraded Smart+ campaign: TikTok automates targeting, bidding and delivery. Supported goals: `conversions`: Smart+ Web Conversions.",
                    "type": "boolean"
                  },
                  "smartTargeting": {
                    "description": "TikTok only (a 400 elsewhere). TikTok Smart Targeting on the ad group. When on, TikTok may deliver beyond the selected audiences or interests. `audience`: TikTok's `smart_audience_enabled`.",
                    "properties": {
                      "audience": {
                        "description": "TikTok smart_audience_enabled.",
                        "type": "boolean"
                      },
                      "interestsBehaviors": {
                        "description": "TikTok smart_interest_behavior_enabled.",
                        "type": "boolean"
                      }
                    },
                    "type": "object"
                  },
                  "specialAdCategories": {
                    "description": "Meta only. Declares the ad's special category, required for housing, employment, credit, or political/social-issue ads (Meta enforces restricted targeting for these). Note: setting a special category disables income/zip targeting on Meta.",
                    "items": {
                      "enum": [
                        "HOUSING",
                        "EMPLOYMENT",
                        "CREDIT",
                        "FINANCIAL_PRODUCTS_SERVICES",
                        "ISSUES_ELECTIONS_POLITICS",
                        "ONLINE_GAMBLING_AND_GAMING"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "specialAdCategoryCountry": {
                    "description": "Meta (metaads) only. 2-letter ISO country codes the special ad category applies to. Requires specialAdCategories to be set (400 otherwise).",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "startDate": {
                    "description": "Ad-set start time (ISO 8601, e.g. \"2026-06-10T09:00:00Z\"). When omitted the ad starts delivering immediately. Same field as on `POST /apis/v1/ads/boost`.",
                    "format": "date-time",
                    "type": "string"
                  },
                  "status": {
                    "description": "Publish state of the created entities, on every platform. Omitted or ACTIVE publishes live (default, back-compat).",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "structuredSnippets": {
                    "description": "Google Search only. Structured snippets: one header from Google's predefined list plus 3-10 values (max 25 chars each). Each becomes one Asset (`structured_snippet_asset`) plus a CampaignAsset link with field_type STRUCTURED_SNIPPET.",
                    "items": {
                      "properties": {
                        "header": {
                          "description": "One of Google's 13 predefined snippet headers.",
                          "enum": [
                            "Amenities",
                            "Brands",
                            "Courses",
                            "Degree programs",
                            "Destinations",
                            "Featured hotels",
                            "Insurance coverage",
                            "Models",
                            "Neighborhoods",
                            "Service catalog",
                            "Shows",
                            "Styles",
                            "Types"
                          ],
                          "type": "string"
                        },
                        "values": {
                          "items": {
                            "maxLength": 25,
                            "minLength": 1,
                            "type": "string"
                          },
                          "maxItems": 10,
                          "minItems": 3,
                          "type": "array"
                        }
                      },
                      "required": [
                        "header",
                        "values"
                      ],
                      "type": "object"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  },
                  "targetImpressionShare": {
                    "additionalProperties": false,
                    "description": "Google Search only. Target impression share bidding. Exclusive with bidStrategy, portfolioBidStrategyId and manualCpc; bidAmount is refused alongside it (the ceiling is maxCpc).",
                    "properties": {
                      "location": {
                        "enum": [
                          "ANYWHERE_ON_PAGE",
                          "TOP_OF_PAGE",
                          "ABSOLUTE_TOP_OF_PAGE"
                        ],
                        "type": "string"
                      },
                      "maxCpc": {
                        "description": "Max CPC bid limit, in the account's currency units. Google requires it.",
                        "exclusiveMinimum": 0,
                        "type": "number"
                      },
                      "percent": {
                        "description": "Target share of impressions, in percent (65 = 65%). Sent to Google as location_fraction_micros (1% = 10,000).",
                        "exclusiveMinimum": 0,
                        "maximum": 100,
                        "type": "number"
                      }
                    },
                    "required": [
                      "location",
                      "maxCpc",
                      "percent"
                    ],
                    "type": "object"
                  },
                  "targeting": {
                    "description": "Nested targeting object: the same TargetingSpec shape as `POST /apis/v1/ads/boost`, `POST /apis/v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences.",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "tracking": {
                    "description": "Ad tracking. Meta, plus `urlTags` on ChatGPT (OpenAI) and `pixelId` on Reddit. Meta: attaches pixel measurement to the ad regardless of the optimization goal (the \"Website events\" tracking row in Ads Manager).",
                    "properties": {
                      "pixelId": {
                        "description": "Meta Pixel ID to attach for offsite-conversion measurement, or the Reddit pixel of the new ad group.",
                        "type": "string"
                      },
                      "urlTags": {
                        "description": "Click-URL params. Meta: stored on the creative as `url_tags` and returned by GET /apis/v1/ads/{adId}/tracking-tags.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "value": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key",
                            "value"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "translations": {
                    "description": "Meta only. Multi-language ads (Dynamic Language Optimization, the \"Languages\" toggle in Ads Manager): ONE ad with per-locale copy and, optionally, per-locale media.",
                    "items": {
                      "properties": {
                        "body": {
                          "description": "Primary text for this language. REQUIRED, and must differ from every other locale and from the ad's top-level body.",
                          "type": "string"
                        },
                        "description": {
                          "description": "Link description for this language. REQUIRED, and must differ from every other locale and from the ad's top-level description.",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "headline": {
                          "description": "Headline for this language. REQUIRED, and must differ from every other locale and from the ad's top-level headline.",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Image for this language. Inherits the ad's `imageUrl` when omitted. The feed is all-image OR all-video.",
                          "format": "uri",
                          "type": "string"
                        },
                        "linkUrl": {
                          "description": "Destination URL for this language. Inherits the ad's top-level `linkUrl` when omitted, and requires it to be present (400 otherwise): the top-level URL is the destination for every locale you did not override.",
                          "format": "uri",
                          "type": "string"
                        },
                        "locale": {
                          "description": "Language code, resolved to Meta's numeric locale id. Bare codes target the '(All)' umbrella (`es` = every Spanish variant); region-qualified codes target the variant (`pt_BR`, `en_GB`).",
                          "type": "string"
                        },
                        "thumbnailUrl": {
                          "description": "Poster frame for this language's video.",
                          "format": "uri",
                          "type": "string"
                        },
                        "videoUrl": {
                          "description": "Video for this language. Inherits the ad's `video.url` when omitted. The feed is all-image OR all-video.",
                          "format": "uri",
                          "type": "string"
                        }
                      },
                      "required": [
                        "body",
                        "description",
                        "headline",
                        "locale"
                      ],
                      "type": "object"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  },
                  "userDevice": {
                    "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                    "items": {
                      "minLength": 1,
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "userOs": {
                    "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                    "items": {
                      "minLength": 1,
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "validateOnly": {
                    "description": "Validate the request without creating anything. Any other platform, or a Google campaignType other than pmax or demand_gen, returns 501 `feature_not_available`.",
                    "type": "boolean"
                  },
                  "valueRuleSetId": {
                    "description": "Meta only (facebook, instagram; other platforms return 400). Value rule set to attach to the new ad set, from `/apis/v1/ads/value-rule-sets`. Attachment is driven by this id, so `valueRulesApplied` is optional alongside it.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "valueRulesApplied": {
                    "description": "Meta only (facebook, instagram; other platforms return 400). Optional when attaching, and requires `valueRuleSetId`.",
                    "type": "boolean"
                  },
                  "video": {
                    "description": "Creates a single VIDEO ad. Meta (facebook, instagram), LinkedIn and Reddit. Mutually exclusive with `imageUrl`. Supply `url` to upload a file, or `id` to reuse a video already on the ad account (list them with GET /apis/v1/ads/videos).",
                    "properties": {
                      "id": {
                        "description": "Meta only. Reuse a video ALREADY uploaded to this ad account instead of re-uploading the file: pass the `videoId` returned by a previous create.",
                        "type": "string"
                      },
                      "thumbnailUrl": {
                        "description": "Public URL of a still-image thumbnail for the video. OPTIONAL. Meta, omitted: the poster is auto-generated from Meta's own preferred video thumbnail (the candidates Ads Manager shows), so video ads usually publish without one.",
                        "format": "uri",
                        "type": "string"
                      },
                      "url": {
                        "description": "Public URL of the video. Meta: uploaded via chunked transfer on /act_X/advideos, then the request blocks on Meta's transcoding until status.video_status === 'ready'.",
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "workEmployers": {
                    "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer. Each must include id.",
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "workIndustries": {
                    "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Each must include id. Rejected on other platforms (use LinkedIn's `industries` there).",
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "workPositions": {
                    "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Each must include id. Rejected on other platforms (use LinkedIn's `jobTitles` there).",
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "zips": {
                    "description": "Postal/ZIP geo targeting. `key` is the platform's postal location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=zip. Supported on Meta, Google, TikTok, Pinterest, X.",
                    "items": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "type": "array"
                  }
                },
                "required": [
                  "adAccountId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "appliedDefaults": {
                      "description": "What the create filled in for fields the request left out. Empty when every field was sent. A passing validateOnly returns it too, so a dry run previews these values before anything is created.",
                      "properties": {
                        "budgetType": {
                          "description": "Sent when `budgetAmount` came without `budgetType`.",
                          "enum": [
                            "daily"
                          ],
                          "type": "string"
                        },
                        "countries": {
                          "description": "Sent when the request sent no countries and the ad gets the long-standing United States default. Not sent on attach, Google Performance Max or Demand Gen, or a Google ad group joining `existingCampaignId`, which keep their own geo.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "endDate": {
                          "description": "Sent when a lifetime budget had no `endDate`: 7 days after the start. A daily budget never gets one and runs until paused. A start with an offset (or no start) gets a UTC instant.",
                          "type": "string"
                        },
                        "goal": {
                          "description": "`lead_generation`: with a `leadGenFormId`. `app_promotion`: when `promotedObject` names an app. `conversions`: with `promotedObject.pixelId` and `customEventType`.",
                          "type": "string"
                        },
                        "name": {
                          "description": "Sent when `name` was omitted: `Ad ` in UTC.",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "message": {
                      "type": "string"
                    },
                    "results": {
                      "items": {
                        "properties": {
                          "node": {
                            "enum": [
                              "campaign",
                              "adSet",
                              "creative",
                              "ad",
                              "performanceMaxCampaign"
                            ],
                            "type": "string"
                          },
                          "reason": {
                            "description": "Explanation for the node's result: On skipped: why the node could not be validated. On unverified: why Meta could not dry-run it although the other nodes passed.",
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "validated",
                              "skipped",
                              "unverified"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "validateOnly": {
                      "description": "Always true in a validate-only response.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "validateOnly dry-run passed, nothing was created"
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Legacy + attach shapes: one ad returned.",
                      "properties": {
                        "ad": {
                          "properties": {
                            "_id": {
                              "type": "string"
                            },
                            "adSetName": {
                              "type": "string"
                            },
                            "adType": {
                              "enum": [
                                "boost",
                                "standalone"
                              ],
                              "type": "string"
                            },
                            "bidAmount": {
                              "description": "Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). Meta: `bid_amount` on the ad set (smallest-denomination int, decoded here).",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "bidStrategy": {
                              "anyOf": [
                                {
                                  "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                                  "enum": [
                                    "LOWEST_COST_WITHOUT_CAP",
                                    "LOWEST_COST_WITH_BID_CAP",
                                    "COST_CAP",
                                    "LOWEST_COST_WITH_MIN_ROAS"
                                  ],
                                  "type": "string"
                                },
                                {
                                  "type": "null"
                                }
                              ],
                              "description": "Ad-set bid strategy (overrides campaign level on Meta). Populated for Meta and TikTok."
                            },
                            "budget": {
                              "properties": {
                                "amount": {
                                  "type": "number"
                                },
                                "daily": {
                                  "description": "LinkedIn and X only. The daily budget (LinkedIn: the parent campaign's `dailyBudget`; X: the line item's, or the campaign's when the line item has none).",
                                  "type": "number"
                                },
                                "lifetime": {
                                  "description": "LinkedIn and X only. The lifetime total (LinkedIn: the parent campaign's `totalBudget`; X: `total_budget_amount_local_micro`, for example the `lifetimeBudgetCap` of a boost), readable even when a daily budget is also set.",
                                  "type": "number"
                                },
                                "pacing": {
                                  "description": "LinkedIn only. The campaign's `pacingStrategy`: how fast LinkedIn may spend the budget. Typically LINEAR or ACCELERATED; the list is open.",
                                  "type": "string"
                                },
                                "type": {
                                  "enum": [
                                    "daily",
                                    "lifetime"
                                  ],
                                  "type": "string"
                                }
                              },
                              "type": [
                                "object",
                                "null"
                              ]
                            },
                            "campaignName": {
                              "type": "string"
                            },
                            "configuredStatus": {
                              "description": "The ad's own on/off switch as configured on the platform, independent of its parents. An ACTIVE ad under a paused ad set or campaign still reads ACTIVE here while `status` reads `paused`. Sources: Meta: `configured_status`.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "costType": {
                              "description": "LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn, refreshed on every sync rather than echoing what was passed on create. `null` for non-LinkedIn ads. `CPM`: cost per thousand impressions.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "createdAt": {
                              "format": "date-time",
                              "type": "string"
                            },
                            "creative": {
                              "description": "Platform-specific creative data. Fields vary by platform.",
                              "properties": {
                                "adFormat": {
                                  "description": "LinkedIn only. The LinkedIn ad format, in LinkedIn's own vocabulary: STANDARD_UPDATE, SINGLE_VIDEO, CAROUSEL, NATIVE_DOCUMENT, EVENT, TEXT_AD, SPOTLIGHT, FOLLOW_COMPANY, JOBS, SPONSORED_INMAILS and others.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "assetGroup": {
                                  "description": "Google Performance Max creative assets. At least one description must be 60 characters or fewer. Texts within each list must be distinct.",
                                  "properties": {
                                    "businessName": {
                                      "maxLength": 25,
                                      "minLength": 1,
                                      "type": "string"
                                    },
                                    "descriptions": {
                                      "description": "At least one description must be 60 characters or fewer.",
                                      "items": {
                                        "maxLength": 90,
                                        "minLength": 1,
                                        "type": "string"
                                      },
                                      "maxItems": 5,
                                      "minItems": 2,
                                      "type": "array",
                                      "uniqueItems": true
                                    },
                                    "finalUrl": {
                                      "description": "Required destination URL.",
                                      "format": "uri",
                                      "pattern": "^https?://",
                                      "type": "string"
                                    },
                                    "headlines": {
                                      "items": {
                                        "maxLength": 30,
                                        "minLength": 1,
                                        "type": "string"
                                      },
                                      "maxItems": 15,
                                      "minItems": 3,
                                      "type": "array",
                                      "uniqueItems": true
                                    },
                                    "images": {
                                      "additionalProperties": true,
                                      "description": "Public HTTP(S) image URLs. GIF, JPEG or PNG, at most 5120 KB per image. Google validates dimensions and aspect ratios.",
                                      "type": "object"
                                    },
                                    "longHeadline": {
                                      "maxLength": 90,
                                      "minLength": 1,
                                      "type": "string"
                                    },
                                    "name": {
                                      "description": "Defaults to the request name.",
                                      "maxLength": 128,
                                      "minLength": 1,
                                      "type": "string"
                                    },
                                    "youtubeVideoId": {
                                      "description": "Optional existing YouTube video id. Google can generate video when omitted. Video uploads and arbitrary video URLs are not supported.",
                                      "pattern": "^[A-Za-z0-9_-]{11}$",
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "businessName",
                                    "descriptions",
                                    "finalUrl",
                                    "headlines",
                                    "images",
                                    "longHeadline"
                                  ],
                                  "type": "object"
                                },
                                "assetGroupResourceName": {
                                  "description": "Google resource name of the created Performance Max asset group.",
                                  "type": "string"
                                },
                                "assetResourceName": {
                                  "description": "Google Display only. Resource name of the landscape marketing image asset (`creative.imageUrl`), for example customers/1234567890/assets/123.",
                                  "type": "string"
                                },
                                "assets": {
                                  "description": "Google Display only. Native Google asset resource name of each image on the responsive display ad, keyed by Google's image role.",
                                  "properties": {
                                    "marketingImages": {
                                      "description": "Landscape (1.91:1) marketing images. The first item matches `assetResourceName`.",
                                      "items": {
                                        "additionalProperties": true,
                                        "type": "object"
                                      },
                                      "type": "array"
                                    },
                                    "squareMarketingImages": {
                                      "description": "Square (1:1) marketing images.",
                                      "items": {
                                        "additionalProperties": true,
                                        "type": "object"
                                      },
                                      "type": "array"
                                    }
                                  },
                                  "type": "object"
                                },
                                "bodies": {
                                  "description": "Meta: every primary text variation of the creative (`asset_feed_spec.bodies`), the same shape as the `bodies` create input. Present only with 2 or more texts; a single text is `body`.",
                                  "items": {
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "body": {
                                  "description": "Ad copy/text",
                                  "type": "string"
                                },
                                "callToAction": {
                                  "description": "Meta: the call to action type (`call_to_action.type`, or the first `asset_feed_spec.call_to_action_types` entry), e.g. LEARN_MORE or SIGN_UP.",
                                  "type": "string"
                                },
                                "carouselCards": {
                                  "description": "Meta only today. The carousel's cards in display order, one per Meta `link_data.child_attachments` entry, using the same field names as the `carouselCards` create input. Absent on non-carousel ads and other platforms.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "catalog": {
                                  "properties": {
                                    "format": {
                                      "description": "object_story_spec.template_data.format_option, from catalogFormat.",
                                      "enum": [
                                        "single_image",
                                        "carousel_images_multi_items",
                                        "carousel_images_single_item",
                                        "carousel_slideshows"
                                      ],
                                      "type": "string"
                                    },
                                    "formatTransformationSpec": {
                                      "description": "The format_transformation_spec sent on the creative, as Meta's raw objects. Present for single_image.",
                                      "items": {
                                        "additionalProperties": true,
                                        "type": "object"
                                      },
                                      "type": "array"
                                    },
                                    "productSetId": {
                                      "description": "The creative's product_set_id.",
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "creativeFeatures": {
                                  "additionalProperties": {
                                    "enum": [
                                      "OPT_IN",
                                      "OPT_OUT"
                                    ],
                                    "type": "string"
                                  },
                                  "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                                  "type": "object"
                                },
                                "creativeId": {
                                  "description": "Meta ad creative id backing this ad, refreshed from Meta on every sync. Reusable via existingCreativeId on POST /apis/v1/ads/create, and readable raw through GET /apis/v1/ads/creatives/{creativeId}.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "description": {
                                  "description": "Meta: the creative's description under the title (`link_data.description`, `video_data.link_description`, or the first `asset_feed_spec.descriptions` entry).",
                                  "type": "string"
                                },
                                "descriptions": {
                                  "description": "Google RSA: the description assets as objects (2 to 4). Meta: every description variation of the creative (`asset_feed_spec.descriptions`) as strings, the same shape as the `descriptions` create input.",
                                  "items": {
                                    "oneOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "additionalProperties": true,
                                        "type": "object"
                                      }
                                    ]
                                  },
                                  "maxItems": 4,
                                  "type": "array"
                                },
                                "effectiveInstagramMediaId": {
                                  "description": "Meta `effective_instagram_media_id`, the Instagram media ID of the boosted post the ad's engagement lives on. Pass to GET /apis/v1/ads?effectiveInstagramMediaId= to map a Business-Manager-visible IG post back to this ad.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "effectiveObjectStoryId": {
                                  "description": "Meta `effective_object_story_id`, the `{pageId}_{postId}` of the Facebook post the ad's engagement (comments) lives on.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "finalUrls": {
                                  "description": "Google RSA only. Replaces final URLs. Omitted lists stay unchanged.",
                                  "items": {
                                    "format": "uri",
                                    "type": "string"
                                  },
                                  "minItems": 1,
                                  "type": "array"
                                },
                                "googleDescription": {
                                  "description": "Google Ads description",
                                  "type": "string"
                                },
                                "googleHeadline": {
                                  "description": "Google Ads headline",
                                  "type": "string"
                                },
                                "headline": {
                                  "description": "Meta: the creative's title (`link_data.name`, `video_data.title`, or the first `asset_feed_spec.titles` entry). Absent when the creative has none.",
                                  "type": "string"
                                },
                                "headlines": {
                                  "description": "Google RSA: the headline assets as objects (3 to 15). Meta: every title variation of the creative (`asset_feed_spec.titles`) as strings, the same shape as the `headlines` create input.",
                                  "items": {
                                    "oneOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "additionalProperties": true,
                                        "type": "object"
                                      }
                                    ]
                                  },
                                  "maxItems": 15,
                                  "type": "array"
                                },
                                "imageHash": {
                                  "description": "Meta: the ad image hash (`image_hash`), reusable as `imageHash` on POST /apis/v1/ads/create within the same ad account. `thumbnailUrl` and `mediaUrls` carry its stable full resolution permalink when Meta resolves it.",
                                  "type": "string"
                                },
                                "imageUrl": {
                                  "description": "Alternative image URL",
                                  "type": "string"
                                },
                                "instagramPermalinkUrl": {
                                  "description": "Meta `instagram_permalink_url`, the public Instagram post URL of the boosted media.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "instagramUserId": {
                                  "description": "Meta `instagram_user_id`, the Instagram-scoped business ID that owns the boosted media.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "instagramVideoFallback": {
                                  "description": "Meta only. `instagram_video_reuploaded`: the video was copied into the ad account, and the ad still references the original post.",
                                  "properties": {
                                    "kind": {
                                      "enum": [
                                        "instagram_video_reuploaded",
                                        "instagram_video_rehosted_copy"
                                      ],
                                      "type": "string"
                                    },
                                    "linkedToOriginalPost": {
                                      "description": "True when the ad still references the original Instagram post and keeps its engagement.",
                                      "type": "boolean"
                                    },
                                    "platformError": {
                                      "additionalProperties": true,
                                      "description": "Meta's original refusal.",
                                      "type": "object"
                                    },
                                    "videoId": {
                                      "description": "instagram_video_reuploaded: the copy in the ad account video library (possibly one made by an earlier boost of the same media, reused).",
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "kind",
                                    "linkedToOriginalPost",
                                    "platformError",
                                    "videoId"
                                  ],
                                  "type": "object"
                                },
                                "isServing": {
                                  "description": "LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign.",
                                  "type": [
                                    "boolean",
                                    "null"
                                  ]
                                },
                                "leadGenFormId": {
                                  "description": "Meta: the instant form the call to action opens (`call_to_action.value.lead_gen_form_id`, or the asset feed's `call_to_actions` on a dynamic creative), the same value as the `leadGenFormId` create input. Absent on ads without a lead form.",
                                  "type": "string"
                                },
                                "linkUrl": {
                                  "description": "Destination URL",
                                  "type": "string"
                                },
                                "mediaUrls": {
                                  "description": "All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts).",
                                  "items": {
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "objectStoryId": {
                                  "description": "Meta creative `object_story_id` (the SHARE reference). Frequently absent, because Meta omits it for SHARE creatives. Use effectiveObjectStoryId instead.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "objectType": {
                                  "description": "Meta creative object_type (e.g. SHARE, VIDEO, PRIVACY_CHECK_FAIL, POST_DELETED). Use this to render state-aware previews: when Meta moderation strips image/video fields, only thumbnailUrl at 64x64 is available.",
                                  "type": "string"
                                },
                                "pageId": {
                                  "description": "Facebook Page backing the creative (Meta only). What the `pageId` filter on /apis/v1/ads, /apis/v1/ads/campaigns and /apis/v1/ads/tree matches against. Absent for non-Meta ads and rare Meta creatives with no page signal.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "pinterestDescription": {
                                  "type": "string"
                                },
                                "pinterestImageUrl": {
                                  "type": "string"
                                },
                                "pinterestTitle": {
                                  "type": "string"
                                },
                                "servingHoldReasons": {
                                  "description": "LinkedIn only. Why this specific creative is not being served. Empty when it is serving.",
                                  "items": {
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "thumbnailUrl": {
                                  "description": "Primary thumbnail/image URL",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "urlTags": {
                                  "description": "Meta: the creative's `url_tags` query string appended to the destination URL.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "videoId": {
                                  "description": "Meta video ID for VIDEO-type ads. Null for non-video ads. Callers that need an embeddable MP4 can call GET /{videoId}?fields=source with the page access token.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "videoUrl": {
                                  "description": "Null for non-video ads.",
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "whatsappPhoneNumber": {
                                  "description": "Explicit E.164 WhatsApp number supplied when creating a Meta boost or messaging ad. Absent when omitted by the caller or on older records.",
                                  "type": "string"
                                },
                                "youtubeVideoIds": {
                                  "description": "Google only. YouTube video ids behind a Video campaign ad (video and responsive video ads) or a Demand Gen video ad, same id as `youtubeVideoId` on Performance Max asset groups.",
                                  "items": {
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": [
                                "object",
                                "null"
                              ]
                            },
                            "creativeType": {
                              "description": "Creative format, classified from the media the creative carries. `null` when the creative carries no media to classify. An unsynced creative and a genuine text-only ad are indistinguishable, so neither is guessed at.",
                              "enum": [
                                "carousel",
                                "video",
                                "document",
                                "image",
                                null
                              ],
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "goal": {
                              "description": "Available goals vary by platform:",
                              "enum": [
                                "engagement",
                                "traffic",
                                "awareness",
                                "video_views",
                                "lead_generation",
                                "lead_conversion",
                                "conversions",
                                "app_promotion",
                                "catalog_sales",
                                "page_likes",
                                "page_visits",
                                "job_applicants"
                              ],
                              "type": "string"
                            },
                            "isExternal": {
                              "description": "True for ads synced from platform ad managers",
                              "type": "boolean"
                            },
                            "metrics": {
                              "anyOf": [
                                {
                                  "properties": {
                                    "actionValues": {
                                      "additionalProperties": {
                                        "type": "number"
                                      },
                                      "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                      "type": "object"
                                    },
                                    "actions": {
                                      "additionalProperties": {
                                        "type": "integer"
                                      },
                                      "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                      "type": "object"
                                    },
                                    "allConversions": {
                                      "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                      "type": "number"
                                    },
                                    "clicks": {
                                      "type": "integer"
                                    },
                                    "conversions": {
                                      "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                      "type": "number"
                                    },
                                    "costPerAction": {
                                      "additionalProperties": {
                                        "type": "number"
                                      },
                                      "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                      "type": "object"
                                    },
                                    "costPerConversion": {
                                      "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                      "type": "number"
                                    },
                                    "costPerThruplay": {
                                      "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                      "type": "number"
                                    },
                                    "cpc": {
                                      "description": "Cost per click",
                                      "type": "number"
                                    },
                                    "cpm": {
                                      "description": "Cost per 1000 impressions",
                                      "type": "number"
                                    },
                                    "ctr": {
                                      "description": "Click-through rate (%)",
                                      "type": "number"
                                    },
                                    "engagement": {
                                      "type": "integer"
                                    },
                                    "engagementBreakdown": {
                                      "description": "The single `engagement` total, split into the interactions behind it.",
                                      "properties": {
                                        "comments": {
                                          "description": "Comments on the ad's post.",
                                          "type": "integer"
                                        },
                                        "linkClicks": {
                                          "description": "Attributed link clicks (`link_click`). This is the attribution-window count, which differs from the in-session count in the sibling `inlineLinkClicks` field.",
                                          "type": "integer"
                                        },
                                        "pageEngagement": {
                                          "description": "Meta's own page-engagement total (`page_engagement`). Meta-only.",
                                          "type": "integer"
                                        },
                                        "pageLikes": {
                                          "description": "New Page likes attributed to the ad (`like`).",
                                          "type": "integer"
                                        },
                                        "postEngagement": {
                                          "description": "Meta's own post-engagement total (`post_engagement`). Meta-only.",
                                          "type": "integer"
                                        },
                                        "reactions": {
                                          "description": "Reactions on the ad's post (`post_reaction`). For TikTok these are its paid likes.",
                                          "type": "integer"
                                        },
                                        "saves": {
                                          "description": "Saves of the ad's post (`onsite_conversion.post_save`).",
                                          "type": "integer"
                                        },
                                        "shares": {
                                          "description": "Shares of the ad's post. Meta reports these under the action type literally named `post`; TikTok under `share`.",
                                          "type": "integer"
                                        },
                                        "videoViews": {
                                          "description": "Video views, from the `video_view` action. Meta counts a 3-second view; LinkedIn's own `videoViews` threshold (2 continuous seconds, or 25% of the video) lands under the same key, so compare across platforms with care.",
                                          "type": "integer"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "funnel": {
                                      "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                      "properties": {
                                        "appInstalls": {
                                          "description": "Mobile app installs attributed to the ad.",
                                          "type": "integer"
                                        },
                                        "cartAdds": {
                                          "description": "Adds to cart (Meta `AddToCart` pixel event).",
                                          "type": "integer"
                                        },
                                        "checkoutsInitiated": {
                                          "description": "Checkouts started (Meta `InitiateCheckout` pixel event).",
                                          "type": "integer"
                                        },
                                        "contentViews": {
                                          "description": "Content views (Meta `ViewContent` pixel event).",
                                          "type": "integer"
                                        },
                                        "landingPageViews": {
                                          "description": "Landing page views: the visitor actually loaded the destination, unlike a link click. Meta `landing_page_view`.",
                                          "type": "integer"
                                        },
                                        "leads": {
                                          "description": "Leads, from either the website pixel or an instant form, whichever the ad uses.",
                                          "type": "integer"
                                        },
                                        "messagingConversationsStarted": {
                                          "description": "Messaging conversations started within 7 days, the headline metric for click-to-WhatsApp and click-to-Messenger ads.",
                                          "type": "integer"
                                        },
                                        "messagingFirstReplies": {
                                          "description": "Messaging threads where the person sent a first reply.",
                                          "type": "integer"
                                        },
                                        "paymentInfoAdds": {
                                          "description": "Payment details added at checkout (Meta `AddPaymentInfo` pixel event).",
                                          "type": "integer"
                                        },
                                        "purchases": {
                                          "description": "Purchases. Pair with `purchaseValue` for revenue.",
                                          "type": "integer"
                                        },
                                        "registrationsCompleted": {
                                          "description": "Completed registrations (Meta `CompleteRegistration` pixel event).",
                                          "type": "integer"
                                        },
                                        "searches": {
                                          "description": "On-site searches (Meta `Search` pixel event).",
                                          "type": "integer"
                                        },
                                        "wishlistAdds": {
                                          "description": "Adds to wishlist (Meta `AddToWishlist` pixel event).",
                                          "type": "integer"
                                        }
                                      },
                                      "type": "object"
                                    },
                                    "impressions": {
                                      "type": "integer"
                                    },
                                    "inlineLinkClickCtr": {
                                      "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                      "type": "number"
                                    },
                                    "inlineLinkClicks": {
                                      "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                      "type": "integer"
                                    },
                                    "lastSyncedAt": {
                                      "description": "Present on individual ads only, not on campaign aggregations",
                                      "format": "date-time",
                                      "type": "string"
                                    },
                                    "outboundClicks": {
                                      "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                      "type": "integer"
                                    },
                                    "outboundClicksCtr": {
                                      "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                      "type": "number"
                                    },
                                    "purchaseValue": {
                                      "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                      "type": "number"
                                    },
                                    "reach": {
                                      "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                      "type": "integer"
                                    },
                                    "roas": {
                                      "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                      "type": "number"
                                    },
                                    "spend": {
                                      "type": "number"
                                    },
                                    "uniqueClicks": {
                                      "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                      "type": "integer"
                                    },
                                    "uniqueCtr": {
                                      "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                      "type": "number"
                                    },
                                    "video2SecWatchedActions": {
                                      "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                      "type": "integer"
                                    },
                                    "video30SecWatchedActions": {
                                      "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                      "type": "integer"
                                    },
                                    "video6SecFocusedViews": {
                                      "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                      "type": "integer"
                                    },
                                    "video6SecWatchedActions": {
                                      "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                      "type": "integer"
                                    },
                                    "videoAvgTimeWatchedActions": {
                                      "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                      "type": "number"
                                    },
                                    "videoP100WatchedActions": {
                                      "description": "Views reaching 100% of the video's length.",
                                      "type": "integer"
                                    },
                                    "videoP25WatchedActions": {
                                      "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                      "type": "integer"
                                    },
                                    "videoP50WatchedActions": {
                                      "description": "Views reaching 50% of the video's length.",
                                      "type": "integer"
                                    },
                                    "videoP75WatchedActions": {
                                      "description": "Views reaching 75% of the video's length.",
                                      "type": "integer"
                                    },
                                    "videoP95WatchedActions": {
                                      "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                      "type": "integer"
                                    },
                                    "videoPlayActions": {
                                      "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                      "type": "integer"
                                    },
                                    "videoThruplayWatchedActions": {
                                      "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            },
                            "name": {
                              "type": "string"
                            },
                            "optimizationGoal": {
                              "description": "What the delivery system optimizes for, at ad-set level. The value space depends on `platform`: Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS).",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "platform": {
                              "enum": [
                                "facebook",
                                "instagram",
                                "tiktok",
                                "linkedin",
                                "pinterest",
                                "google",
                                "twitter",
                                "openai",
                                "reddit",
                                "microsoft"
                              ],
                              "type": "string"
                            },
                            "platformAdAccountId": {
                              "type": "string"
                            },
                            "platformAdAccountName": {
                              "description": "Human-readable advertiser/account name (Meta `AdAccount.name`, TikTok `advertiser_name`, LinkedIn / X / Pinterest equivalents). Refreshed every sync so platform-side renames propagate within one cycle.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "platformAdId": {
                              "type": "string"
                            },
                            "platformAdSetId": {
                              "type": "string"
                            },
                            "platformCampaignId": {
                              "type": "string"
                            },
                            "platformCreatedAt": {
                              "description": "Platform-reported creation timestamp (Meta `created_time`, TikTok `create_time`). Read this field to sort or filter by when the ad was actually created on the platform.",
                              "format": "date-time",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "platformObjective": {
                              "description": "The platform's own campaign objective, verbatim, alongside the normalized `goal` it maps to. The mapping is many-to-one, so `goal` alone cannot be mapped back to it. Meta: campaign `objective` (e.g.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "promotedObject": {
                              "description": "Meta promoted object containing conversion event details. Structure varies by objective. Only present for Meta ads.",
                              "properties": {
                                "application_id": {
                                  "description": "Facebook app ID",
                                  "type": "string"
                                },
                                "custom_event_type": {
                                  "description": "Conversion event type (e.g. PURCHASE, LEAD, COMPLETE_REGISTRATION, ADD_TO_CART)",
                                  "type": "string"
                                },
                                "page_id": {
                                  "description": "Facebook page ID",
                                  "type": "string"
                                },
                                "pixel_id": {
                                  "description": "Meta pixel ID",
                                  "type": "string"
                                },
                                "product_set_id": {
                                  "description": "Product catalog set ID",
                                  "type": "string"
                                }
                              },
                              "type": [
                                "object",
                                "null"
                              ]
                            },
                            "rejectionReason": {
                              "type": "string"
                            },
                            "reviewStatus": {
                              "description": "Platform review state of this ad, independent of delivery `status` / `configuredStatus`. Absent when the platform reports no review signal.",
                              "enum": [
                                "in_review",
                                "approved",
                                "rejected",
                                "with_issues"
                              ],
                              "type": "string"
                            },
                            "roasAverageFloor": {
                              "description": "Minimum ROAS as a decimal multiplier (2.0 = 2.0x ROAS). Populated when bidStrategy is `LOWEST_COST_WITH_MIN_ROAS`.",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "schedule": {
                              "description": "Delivery window as UTC instants.",
                              "properties": {
                                "endDate": {
                                  "format": "date-time",
                                  "type": "string"
                                },
                                "startDate": {
                                  "format": "date-time",
                                  "type": "string"
                                }
                              },
                              "type": [
                                "object",
                                "null"
                              ]
                            },
                            "servingStatuses": {
                              "description": "LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn. A campaign can report `status: ACTIVE` and still serve nothing; this array says so.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "status": {
                              "description": "Delivery status. Derived from the platform `effective_status`, so it inherits ancestor pauses (an ACTIVE ad under a PAUSED campaign reads `paused`).",
                              "enum": [
                                "active",
                                "paused",
                                "pending_review",
                                "rejected",
                                "completed",
                                "cancelled",
                                "error"
                              ],
                              "type": "string"
                            },
                            "synced": {
                              "description": "Only on GET /apis/v1/ads/{adId}. An unsynced ad has no `id`.",
                              "type": "boolean"
                            },
                            "targeting": {
                              "description": "The ad set's targeting (age, gender, geo, interests, placements, audience inclusions/exclusions). May be absent if the ad set exposes no targeting or the lookup fails.",
                              "type": "object"
                            },
                            "updatedAt": {
                              "format": "date-time",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "appliedDefaults": {
                          "description": "What the create filled in for fields the request left out. Empty when every field was sent. A passing validateOnly returns it too, so a dry run previews these values before anything is created.",
                          "properties": {
                            "budgetType": {
                              "description": "Sent when `budgetAmount` came without `budgetType`.",
                              "enum": [
                                "daily"
                              ],
                              "type": "string"
                            },
                            "countries": {
                              "description": "Sent when the request sent no countries and the ad gets the long-standing United States default. Not sent on attach, Google Performance Max or Demand Gen, or a Google ad group joining `existingCampaignId`, which keep their own geo.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "endDate": {
                              "description": "Sent when a lifetime budget had no `endDate`: 7 days after the start. A daily budget never gets one and runs until paused. A start with an offset (or no start) gets a UTC instant.",
                              "type": "string"
                            },
                            "goal": {
                              "description": "`lead_generation`: with a `leadGenFormId`. `app_promotion`: when `promotedObject` names an app. `conversions`: with `promotedObject.pixelId` and `customEventType`.",
                              "type": "string"
                            },
                            "name": {
                              "description": "Sent when `name` was omitted: `Ad ` in UTC.",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "message": {
                          "type": "string"
                        },
                        "warnings": {
                          "description": "Meta only, present only when needed. An `activation_failed:` entry means Meta refused the final switch to ACTIVE.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    },
                    {
                      "description": "Multi-creative shape: N ads returned sharing platformCampaignId / platformAdSetId.",
                      "properties": {
                        "ads": {
                          "items": {
                            "properties": {
                              "_id": {
                                "type": "string"
                              },
                              "adSetName": {
                                "type": "string"
                              },
                              "adType": {
                                "enum": [
                                  "boost",
                                  "standalone"
                                ],
                                "type": "string"
                              },
                              "bidAmount": {
                                "description": "Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). Meta: `bid_amount` on the ad set (smallest-denomination int, decoded here).",
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "bidStrategy": {
                                "anyOf": [
                                  {
                                    "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                                    "enum": [
                                      "LOWEST_COST_WITHOUT_CAP",
                                      "LOWEST_COST_WITH_BID_CAP",
                                      "COST_CAP",
                                      "LOWEST_COST_WITH_MIN_ROAS"
                                    ],
                                    "type": "string"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "Ad-set bid strategy (overrides campaign level on Meta). Populated for Meta and TikTok."
                              },
                              "budget": {
                                "properties": {
                                  "amount": {
                                    "type": "number"
                                  },
                                  "daily": {
                                    "description": "LinkedIn and X only. The daily budget (LinkedIn: the parent campaign's `dailyBudget`; X: the line item's, or the campaign's when the line item has none).",
                                    "type": "number"
                                  },
                                  "lifetime": {
                                    "description": "LinkedIn and X only. The lifetime total (LinkedIn: the parent campaign's `totalBudget`; X: `total_budget_amount_local_micro`, for example the `lifetimeBudgetCap` of a boost), readable even when a daily budget is also set.",
                                    "type": "number"
                                  },
                                  "pacing": {
                                    "description": "LinkedIn only. The campaign's `pacingStrategy`: how fast LinkedIn may spend the budget. Typically LINEAR or ACCELERATED; the list is open.",
                                    "type": "string"
                                  },
                                  "type": {
                                    "enum": [
                                      "daily",
                                      "lifetime"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "type": [
                                  "object",
                                  "null"
                                ]
                              },
                              "campaignName": {
                                "type": "string"
                              },
                              "configuredStatus": {
                                "description": "The ad's own on/off switch as configured on the platform, independent of its parents. An ACTIVE ad under a paused ad set or campaign still reads ACTIVE here while `status` reads `paused`. Sources: Meta: `configured_status`.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "costType": {
                                "description": "LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn, refreshed on every sync rather than echoing what was passed on create. `null` for non-LinkedIn ads. `CPM`: cost per thousand impressions.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "createdAt": {
                                "format": "date-time",
                                "type": "string"
                              },
                              "creative": {
                                "description": "Platform-specific creative data. Fields vary by platform.",
                                "properties": {
                                  "adFormat": {
                                    "description": "LinkedIn only. The LinkedIn ad format, in LinkedIn's own vocabulary: STANDARD_UPDATE, SINGLE_VIDEO, CAROUSEL, NATIVE_DOCUMENT, EVENT, TEXT_AD, SPOTLIGHT, FOLLOW_COMPANY, JOBS, SPONSORED_INMAILS and others.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "assetGroup": {
                                    "additionalProperties": true,
                                    "description": "Google Performance Max creative assets. At least one description must be 60 characters or fewer. Texts within each list must be distinct.",
                                    "type": "object"
                                  },
                                  "assetGroupResourceName": {
                                    "description": "Google resource name of the created Performance Max asset group.",
                                    "type": "string"
                                  },
                                  "assetResourceName": {
                                    "description": "Google Display only. Resource name of the landscape marketing image asset (`creative.imageUrl`), for example customers/1234567890/assets/123.",
                                    "type": "string"
                                  },
                                  "assets": {
                                    "additionalProperties": true,
                                    "description": "Google Display only. Native Google asset resource name of each image on the responsive display ad, keyed by Google's image role.",
                                    "type": "object"
                                  },
                                  "bodies": {
                                    "description": "Meta: every primary text variation of the creative (`asset_feed_spec.bodies`), the same shape as the `bodies` create input. Present only with 2 or more texts; a single text is `body`.",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "body": {
                                    "description": "Ad copy/text",
                                    "type": "string"
                                  },
                                  "callToAction": {
                                    "description": "Meta: the call to action type (`call_to_action.type`, or the first `asset_feed_spec.call_to_action_types` entry), e.g. LEARN_MORE or SIGN_UP.",
                                    "type": "string"
                                  },
                                  "carouselCards": {
                                    "description": "Meta only today. The carousel's cards in display order, one per Meta `link_data.child_attachments` entry, using the same field names as the `carouselCards` create input. Absent on non-carousel ads and other platforms.",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "catalog": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "creativeFeatures": {
                                    "additionalProperties": true,
                                    "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                                    "type": "object"
                                  },
                                  "creativeId": {
                                    "description": "Meta ad creative id backing this ad, refreshed from Meta on every sync. Reusable via existingCreativeId on POST /apis/v1/ads/create, and readable raw through GET /apis/v1/ads/creatives/{creativeId}.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "description": {
                                    "description": "Meta: the creative's description under the title (`link_data.description`, `video_data.link_description`, or the first `asset_feed_spec.descriptions` entry).",
                                    "type": "string"
                                  },
                                  "descriptions": {
                                    "description": "Google RSA: the description assets as objects (2 to 4). Meta: every description variation of the creative (`asset_feed_spec.descriptions`) as strings, the same shape as the `descriptions` create input.",
                                    "items": {
                                      "oneOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "additionalProperties": true,
                                          "type": "object"
                                        }
                                      ]
                                    },
                                    "maxItems": 4,
                                    "type": "array"
                                  },
                                  "effectiveInstagramMediaId": {
                                    "description": "Meta `effective_instagram_media_id`, the Instagram media ID of the boosted post the ad's engagement lives on. Pass to GET /apis/v1/ads?effectiveInstagramMediaId= to map a Business-Manager-visible IG post back to this ad.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "effectiveObjectStoryId": {
                                    "description": "Meta `effective_object_story_id`, the `{pageId}_{postId}` of the Facebook post the ad's engagement (comments) lives on.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "finalUrls": {
                                    "description": "Google RSA only. Replaces final URLs. Omitted lists stay unchanged.",
                                    "items": {
                                      "format": "uri",
                                      "type": "string"
                                    },
                                    "minItems": 1,
                                    "type": "array"
                                  },
                                  "googleDescription": {
                                    "description": "Google Ads description",
                                    "type": "string"
                                  },
                                  "googleHeadline": {
                                    "description": "Google Ads headline",
                                    "type": "string"
                                  },
                                  "headline": {
                                    "description": "Meta: the creative's title (`link_data.name`, `video_data.title`, or the first `asset_feed_spec.titles` entry). Absent when the creative has none.",
                                    "type": "string"
                                  },
                                  "headlines": {
                                    "description": "Google RSA: the headline assets as objects (3 to 15). Meta: every title variation of the creative (`asset_feed_spec.titles`) as strings, the same shape as the `headlines` create input.",
                                    "items": {
                                      "oneOf": [
                                        {
                                          "type": "string"
                                        },
                                        {
                                          "additionalProperties": true,
                                          "type": "object"
                                        }
                                      ]
                                    },
                                    "maxItems": 15,
                                    "type": "array"
                                  },
                                  "imageHash": {
                                    "description": "Meta: the ad image hash (`image_hash`), reusable as `imageHash` on POST /apis/v1/ads/create within the same ad account. `thumbnailUrl` and `mediaUrls` carry its stable full resolution permalink when Meta resolves it.",
                                    "type": "string"
                                  },
                                  "imageUrl": {
                                    "description": "Alternative image URL",
                                    "type": "string"
                                  },
                                  "instagramPermalinkUrl": {
                                    "description": "Meta `instagram_permalink_url`, the public Instagram post URL of the boosted media.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "instagramUserId": {
                                    "description": "Meta `instagram_user_id`, the Instagram-scoped business ID that owns the boosted media.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "instagramVideoFallback": {
                                    "additionalProperties": true,
                                    "description": "Meta only. `instagram_video_reuploaded`: the video was copied into the ad account, and the ad still references the original post.",
                                    "type": "object"
                                  },
                                  "isServing": {
                                    "description": "LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign.",
                                    "type": [
                                      "boolean",
                                      "null"
                                    ]
                                  },
                                  "leadGenFormId": {
                                    "description": "Meta: the instant form the call to action opens (`call_to_action.value.lead_gen_form_id`, or the asset feed's `call_to_actions` on a dynamic creative), the same value as the `leadGenFormId` create input. Absent on ads without a lead form.",
                                    "type": "string"
                                  },
                                  "linkUrl": {
                                    "description": "Destination URL",
                                    "type": "string"
                                  },
                                  "mediaUrls": {
                                    "description": "All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts).",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "objectStoryId": {
                                    "description": "Meta creative `object_story_id` (the SHARE reference). Frequently absent, because Meta omits it for SHARE creatives. Use effectiveObjectStoryId instead.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "objectType": {
                                    "description": "Meta creative object_type (e.g. SHARE, VIDEO, PRIVACY_CHECK_FAIL, POST_DELETED). Use this to render state-aware previews: when Meta moderation strips image/video fields, only thumbnailUrl at 64x64 is available.",
                                    "type": "string"
                                  },
                                  "pageId": {
                                    "description": "Facebook Page backing the creative (Meta only). What the `pageId` filter on /apis/v1/ads, /apis/v1/ads/campaigns and /apis/v1/ads/tree matches against. Absent for non-Meta ads and rare Meta creatives with no page signal.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "pinterestDescription": {
                                    "type": "string"
                                  },
                                  "pinterestImageUrl": {
                                    "type": "string"
                                  },
                                  "pinterestTitle": {
                                    "type": "string"
                                  },
                                  "servingHoldReasons": {
                                    "description": "LinkedIn only. Why this specific creative is not being served. Empty when it is serving.",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  },
                                  "thumbnailUrl": {
                                    "description": "Primary thumbnail/image URL",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "urlTags": {
                                    "description": "Meta: the creative's `url_tags` query string appended to the destination URL.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "videoId": {
                                    "description": "Meta video ID for VIDEO-type ads. Null for non-video ads. Callers that need an embeddable MP4 can call GET /{videoId}?fields=source with the page access token.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "videoUrl": {
                                    "description": "Null for non-video ads.",
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  },
                                  "whatsappPhoneNumber": {
                                    "description": "Explicit E.164 WhatsApp number supplied when creating a Meta boost or messaging ad. Absent when omitted by the caller or on older records.",
                                    "type": "string"
                                  },
                                  "youtubeVideoIds": {
                                    "description": "Google only. YouTube video ids behind a Video campaign ad (video and responsive video ads) or a Demand Gen video ad, same id as `youtubeVideoId` on Performance Max asset groups.",
                                    "items": {
                                      "type": "string"
                                    },
                                    "type": "array"
                                  }
                                },
                                "type": [
                                  "object",
                                  "null"
                                ]
                              },
                              "creativeType": {
                                "description": "Creative format, classified from the media the creative carries. `null` when the creative carries no media to classify. An unsynced creative and a genuine text-only ad are indistinguishable, so neither is guessed at.",
                                "enum": [
                                  "carousel",
                                  "video",
                                  "document",
                                  "image",
                                  null
                                ],
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "goal": {
                                "description": "Available goals vary by platform:",
                                "enum": [
                                  "engagement",
                                  "traffic",
                                  "awareness",
                                  "video_views",
                                  "lead_generation",
                                  "lead_conversion",
                                  "conversions",
                                  "app_promotion",
                                  "catalog_sales",
                                  "page_likes",
                                  "page_visits",
                                  "job_applicants"
                                ],
                                "type": "string"
                              },
                              "isExternal": {
                                "description": "True for ads synced from platform ad managers",
                                "type": "boolean"
                              },
                              "metrics": {
                                "anyOf": [
                                  {
                                    "properties": {
                                      "actionValues": {
                                        "additionalProperties": true,
                                        "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                        "type": "object"
                                      },
                                      "actions": {
                                        "additionalProperties": true,
                                        "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                        "type": "object"
                                      },
                                      "allConversions": {
                                        "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                        "type": "number"
                                      },
                                      "clicks": {
                                        "type": "integer"
                                      },
                                      "conversions": {
                                        "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                        "type": "number"
                                      },
                                      "costPerAction": {
                                        "additionalProperties": true,
                                        "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                        "type": "object"
                                      },
                                      "costPerConversion": {
                                        "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                        "type": "number"
                                      },
                                      "costPerThruplay": {
                                        "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                        "type": "number"
                                      },
                                      "cpc": {
                                        "description": "Cost per click",
                                        "type": "number"
                                      },
                                      "cpm": {
                                        "description": "Cost per 1000 impressions",
                                        "type": "number"
                                      },
                                      "ctr": {
                                        "description": "Click-through rate (%)",
                                        "type": "number"
                                      },
                                      "engagement": {
                                        "type": "integer"
                                      },
                                      "engagementBreakdown": {
                                        "additionalProperties": true,
                                        "description": "The single `engagement` total, split into the interactions behind it.",
                                        "type": "object"
                                      },
                                      "funnel": {
                                        "additionalProperties": true,
                                        "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                        "type": "object"
                                      },
                                      "impressions": {
                                        "type": "integer"
                                      },
                                      "inlineLinkClickCtr": {
                                        "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                        "type": "number"
                                      },
                                      "inlineLinkClicks": {
                                        "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                        "type": "integer"
                                      },
                                      "lastSyncedAt": {
                                        "description": "Present on individual ads only, not on campaign aggregations",
                                        "format": "date-time",
                                        "type": "string"
                                      },
                                      "outboundClicks": {
                                        "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                        "type": "integer"
                                      },
                                      "outboundClicksCtr": {
                                        "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                        "type": "number"
                                      },
                                      "purchaseValue": {
                                        "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                        "type": "number"
                                      },
                                      "reach": {
                                        "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                        "type": "integer"
                                      },
                                      "roas": {
                                        "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                        "type": "number"
                                      },
                                      "spend": {
                                        "type": "number"
                                      },
                                      "uniqueClicks": {
                                        "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                        "type": "integer"
                                      },
                                      "uniqueCtr": {
                                        "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                        "type": "number"
                                      },
                                      "video2SecWatchedActions": {
                                        "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                        "type": "integer"
                                      },
                                      "video30SecWatchedActions": {
                                        "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                        "type": "integer"
                                      },
                                      "video6SecFocusedViews": {
                                        "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                        "type": "integer"
                                      },
                                      "video6SecWatchedActions": {
                                        "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                        "type": "integer"
                                      },
                                      "videoAvgTimeWatchedActions": {
                                        "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                        "type": "number"
                                      },
                                      "videoP100WatchedActions": {
                                        "description": "Views reaching 100% of the video's length.",
                                        "type": "integer"
                                      },
                                      "videoP25WatchedActions": {
                                        "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                        "type": "integer"
                                      },
                                      "videoP50WatchedActions": {
                                        "description": "Views reaching 50% of the video's length.",
                                        "type": "integer"
                                      },
                                      "videoP75WatchedActions": {
                                        "description": "Views reaching 75% of the video's length.",
                                        "type": "integer"
                                      },
                                      "videoP95WatchedActions": {
                                        "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                        "type": "integer"
                                      },
                                      "videoPlayActions": {
                                        "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                        "type": "integer"
                                      },
                                      "videoThruplayWatchedActions": {
                                        "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                        "type": "integer"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              },
                              "name": {
                                "type": "string"
                              },
                              "optimizationGoal": {
                                "description": "What the delivery system optimizes for, at ad-set level. The value space depends on `platform`: Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS).",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "platform": {
                                "enum": [
                                  "facebook",
                                  "instagram",
                                  "tiktok",
                                  "linkedin",
                                  "pinterest",
                                  "google",
                                  "twitter",
                                  "openai",
                                  "reddit",
                                  "microsoft"
                                ],
                                "type": "string"
                              },
                              "platformAdAccountId": {
                                "type": "string"
                              },
                              "platformAdAccountName": {
                                "description": "Human-readable advertiser/account name (Meta `AdAccount.name`, TikTok `advertiser_name`, LinkedIn / X / Pinterest equivalents). Refreshed every sync so platform-side renames propagate within one cycle.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "platformAdId": {
                                "type": "string"
                              },
                              "platformAdSetId": {
                                "type": "string"
                              },
                              "platformCampaignId": {
                                "type": "string"
                              },
                              "platformCreatedAt": {
                                "description": "Platform-reported creation timestamp (Meta `created_time`, TikTok `create_time`). Read this field to sort or filter by when the ad was actually created on the platform.",
                                "format": "date-time",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "platformObjective": {
                                "description": "The platform's own campaign objective, verbatim, alongside the normalized `goal` it maps to. The mapping is many-to-one, so `goal` alone cannot be mapped back to it. Meta: campaign `objective` (e.g.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "promotedObject": {
                                "description": "Meta promoted object containing conversion event details. Structure varies by objective. Only present for Meta ads.",
                                "properties": {
                                  "application_id": {
                                    "description": "Facebook app ID",
                                    "type": "string"
                                  },
                                  "custom_event_type": {
                                    "description": "Conversion event type (e.g. PURCHASE, LEAD, COMPLETE_REGISTRATION, ADD_TO_CART)",
                                    "type": "string"
                                  },
                                  "page_id": {
                                    "description": "Facebook page ID",
                                    "type": "string"
                                  },
                                  "pixel_id": {
                                    "description": "Meta pixel ID",
                                    "type": "string"
                                  },
                                  "product_set_id": {
                                    "description": "Product catalog set ID",
                                    "type": "string"
                                  }
                                },
                                "type": [
                                  "object",
                                  "null"
                                ]
                              },
                              "rejectionReason": {
                                "type": "string"
                              },
                              "reviewStatus": {
                                "description": "Platform review state of this ad, independent of delivery `status` / `configuredStatus`. Absent when the platform reports no review signal.",
                                "enum": [
                                  "in_review",
                                  "approved",
                                  "rejected",
                                  "with_issues"
                                ],
                                "type": "string"
                              },
                              "roasAverageFloor": {
                                "description": "Minimum ROAS as a decimal multiplier (2.0 = 2.0x ROAS). Populated when bidStrategy is `LOWEST_COST_WITH_MIN_ROAS`.",
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "schedule": {
                                "description": "Delivery window as UTC instants.",
                                "properties": {
                                  "endDate": {
                                    "format": "date-time",
                                    "type": "string"
                                  },
                                  "startDate": {
                                    "format": "date-time",
                                    "type": "string"
                                  }
                                },
                                "type": [
                                  "object",
                                  "null"
                                ]
                              },
                              "servingStatuses": {
                                "description": "LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn. A campaign can report `status: ACTIVE` and still serve nothing; this array says so.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "status": {
                                "description": "Delivery status. Derived from the platform `effective_status`, so it inherits ancestor pauses (an ACTIVE ad under a PAUSED campaign reads `paused`).",
                                "enum": [
                                  "active",
                                  "paused",
                                  "pending_review",
                                  "rejected",
                                  "completed",
                                  "cancelled",
                                  "error"
                                ],
                                "type": "string"
                              },
                              "synced": {
                                "description": "Only on GET /apis/v1/ads/{adId}. An unsynced ad has no `id`.",
                                "type": "boolean"
                              },
                              "targeting": {
                                "description": "The ad set's targeting (age, gender, geo, interests, placements, audience inclusions/exclusions). May be absent if the ad set exposes no targeting or the lookup fails.",
                                "type": "object"
                              },
                              "updatedAt": {
                                "format": "date-time",
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "appliedDefaults": {
                          "description": "What the create filled in for fields the request left out. Empty when every field was sent. A passing validateOnly returns it too, so a dry run previews these values before anything is created.",
                          "properties": {
                            "budgetType": {
                              "description": "Sent when `budgetAmount` came without `budgetType`.",
                              "enum": [
                                "daily"
                              ],
                              "type": "string"
                            },
                            "countries": {
                              "description": "Sent when the request sent no countries and the ad gets the long-standing United States default. Not sent on attach, Google Performance Max or Demand Gen, or a Google ad group joining `existingCampaignId`, which keep their own geo.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "endDate": {
                              "description": "Sent when a lifetime budget had no `endDate`: 7 days after the start. A daily budget never gets one and runs until paused. A start with an offset (or no start) gets a UTC instant.",
                              "type": "string"
                            },
                            "goal": {
                              "description": "`lead_generation`: with a `leadGenFormId`. `app_promotion`: when `promotedObject` names an app. `conversions`: with `promotedObject.pixelId` and `customEventType`.",
                              "type": "string"
                            },
                            "name": {
                              "description": "Sent when `name` was omitted: `Ad ` in UTC.",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "message": {
                          "type": "string"
                        },
                        "platformAdSetId": {
                          "type": "string"
                        },
                        "platformCampaignId": {
                          "type": "string"
                        },
                        "warnings": {
                          "description": "Meta only, present only when needed. An `activation_failed:` entry means Meta refused the final switch to ACTIVE for the ads it names (or for their ad set or campaign).",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Ad(s) created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create standalone ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_standalone_ad@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "b82ffa7bbcb8c87c1c035e8b98ecc4a6d438f6bd966c622650d8c4237c734507"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_create",
          "method": "POST",
          "path": "/apis/v1/ads/create"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_create"
      }
    },
    "/apis/v1/ads/creatives": {
      "get": {
        "description": "Ad Creatives. Read only. Lists the creatives saved in a Meta ad account so you can reuse one in a new ad. Lists the ad account's creative library (Meta's `/act_X/adcreatives`), rows returned verbatim. The default projection covers id, name, status, object type, thumbnail, object_story_spec / asset_feed_spec and url_tags; `fields` is a raw-passthrough override.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_creatives",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Graph field override.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Rows per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "description": "Raw Meta creative row.",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Creatives (raw Meta shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Creative library",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_creatives@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "2b474d95b64b676f473155ee66758fccf34db0246208fde7a543062d5dfef4ff"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_creatives",
          "method": "GET",
          "path": "/apis/v1/ads/creatives"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_creatives"
      },
      "post": {
        "description": "Ad Creatives. Changes the ad account without starting or raising spend; audited. Creates a reusable Meta creative from an image or carousel without creating an ad, ready to attach to ads later. The creative goes in the library WITHOUT an ad, reusable on the create endpoints via `existingCreativeId`. ### Source Provide exactly one of: `imageUrl` (uploaded server-side) `imageHash` (from POST /apis/v1/ads/images or the library list) `carouselCards` (2-10 hand-built cards)\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_creatives",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_123456789",
                "body": "Use SAVE20 at checkout.",
                "connectionId": "adc_7f3k2m9q",
                "creativeFeatures": {
                  "auto_promotion_tag": "OPT_OUT"
                },
                "headline": "Save on your next order",
                "imageUrl": "https://example.com/ad.jpg",
                "linkUrl": "https://example.com/shop"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account id (Meta act_, Google customer id, LinkedIn account id, ...).",
                    "type": "string"
                  },
                  "aiDisclosure": {
                    "description": "Meta only. Meta's \"Ad includes media created or edited with AI\" disclosure (the Ads Manager checkbox), stored on the creative as `generative_asset_spec.transparency_metadata.self_disclosure`. OPT_IN: checks it.",
                    "enum": [
                      "OPT_IN",
                      "OPT_OUT"
                    ],
                    "type": "string"
                  },
                  "body": {
                    "description": "Primary text",
                    "type": "string"
                  },
                  "callToAction": {
                    "default": "LEARN_MORE",
                    "description": "CTA type (same whitelist as POST /apis/v1/ads/create).",
                    "type": "string"
                  },
                  "carouselCards": {
                    "items": {
                      "properties": {
                        "callToAction": {
                          "type": "string"
                        },
                        "description": {
                          "maxLength": 255,
                          "type": "string"
                        },
                        "headline": {
                          "maxLength": 255,
                          "type": "string"
                        },
                        "imageUrl": {
                          "format": "uri",
                          "type": "string"
                        },
                        "linkUrl": {
                          "format": "uri",
                          "type": "string"
                        }
                      },
                      "required": [
                        "imageUrl",
                        "linkUrl"
                      ],
                      "type": "object"
                    },
                    "maxItems": 10,
                    "minItems": 2,
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "creativeFeatures": {
                    "additionalProperties": {
                      "enum": [
                        "OPT_IN",
                        "OPT_OUT"
                      ],
                      "type": "string"
                    },
                    "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                    "type": "object"
                  },
                  "description": {
                    "description": "Link description below the headline; omitted = Meta scrapes the destination's OG description.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "headline": {
                    "maxLength": 255,
                    "type": "string"
                  },
                  "imageHash": {
                    "description": "Existing library image hash (POST /apis/v1/ads/images or GET /apis/v1/ads/images).",
                    "type": "string"
                  },
                  "imageUrl": {
                    "description": "Publicly reachable image; uploaded to the account's library server-side.",
                    "format": "uri",
                    "type": "string"
                  },
                  "linkUrl": {
                    "format": "uri",
                    "type": "string"
                  },
                  "multiAdvertiser": {
                    "description": "Meta only. Multi-advertiser ads: whether Meta may show this ad alongside other advertisers' in one unit. Meta auto-enrols since Aug 2024, so send OPT_OUT to leave.",
                    "enum": [
                      "OPT_IN",
                      "OPT_OUT"
                    ],
                    "type": "string"
                  },
                  "optimizeCardOrder": {
                    "description": "Only with `carouselCards` (a 400 without them). Sets `link_data.multi_share_optimized`: `false`: keeps the cards in the order given. Meta then takes at most 5 cards, so `false` with more than 5 cards is a 400.",
                    "type": "boolean"
                  },
                  "promotion": {
                    "description": "Not supported. Send null or omit the field, and set the Promotion on the ad in Ads Manager. Any object is rejected with 400 invalid_field_value.",
                    "type": [
                      "object",
                      "null"
                    ]
                  },
                  "urlTags": {
                    "description": "Appended to every outbound URL (e.g. utm_source=fb).",
                    "type": "string"
                  }
                },
                "required": [
                  "adAccountId",
                  "body",
                  "headline",
                  "linkUrl"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "creativeId": {
                      "description": "Platform creative id, reusable via existingCreativeId.",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Creative created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a standalone creative",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_creative@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "44fb34f25e34a308b0c4448b7ccd0a63c5e4bf553b38d707f218dbe199dbfb26"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_creatives",
          "method": "POST",
          "path": "/apis/v1/ads/creatives"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_creatives"
      }
    },
    "/apis/v1/ads/creatives/{creativeId}": {
      "delete": {
        "description": "Ad Creatives. Changes the ad account without starting or raising spend; audited. Deletes a Meta creative from the library, which Meta only allows when no ad uses it. Meta only allows deleting creatives not referenced by any ad; otherwise its 400 surfaces verbatim.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_creatives_creativeid",
        "parameters": [
          {
            "description": "Platform creative id",
            "in": "path",
            "name": "creativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "creativeId": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Creative deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete a creative",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_creative@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "8854ddf07815b83ea4df18fdb6fb2a9c6d2af25469d36b4923982f50943b2f35"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_creatives_creativeid",
          "method": "DELETE",
          "path": "/apis/v1/ads/creatives/{creativeId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_creatives_creativeid"
      },
      "get": {
        "description": "Ad Creatives. Read only. Shows the details of one Meta creative, such as its content, status and thumbnail. One creative's details, verbatim from Meta. `fields` is a raw-passthrough override of the default projection.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_creatives_creativeid",
        "parameters": [
          {
            "description": "Platform creative id",
            "in": "path",
            "name": "creativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Graph field override.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Width in pixels of the `thumbnail_url` rendering, forwarded to Meta as `thumbnail_width`. Without it Meta returns a 64x64 thumbnail.",
            "in": "query",
            "name": "thumbnailWidth",
            "required": false,
            "schema": {
              "maximum": 4096,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Height in pixels of the `thumbnail_url` rendering, forwarded to Meta as `thumbnail_height`. Without it Meta returns a 64x64 thumbnail.",
            "in": "query",
            "name": "thumbnailHeight",
            "required": false,
            "schema": {
              "maximum": 4096,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "creative": {
                      "description": "Raw Meta creative node",
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Creative details"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Creative details",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_creative@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "31e808f1ef92d91e0309073098055581a4b1c8fa89221973d96f4b3bc41f0aae"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_creatives_creativeid",
          "method": "GET",
          "path": "/apis/v1/ads/creatives/{creativeId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_creatives_creativeid"
      },
      "put": {
        "description": "Ad Creatives. Changes the ad account without starting or raising spend; audited. Renames a Meta creative (Meta does not allow other changes, so make a new creative to change its content). Creatives are immutable on Meta beyond `name`. For content changes create a new creative (POST /apis/v1/ads/creatives) and swap it onto the ad (PUT /apis/v1/ads/{adId} with `creative`).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_creatives_creativeid",
        "parameters": [
          {
            "description": "Platform creative id",
            "in": "path",
            "name": "creativeId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "creativeId": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Creative renamed"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Rename a creative",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_creative@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "2ff7f3ef75e36cecb07cf2665e88a1cd667ce58b8721e023462e67090b25c9a7"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_creatives_creativeid",
          "method": "PUT",
          "path": "/apis/v1/ads/creatives/{creativeId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_creatives_creativeid"
      }
    },
    "/apis/v1/ads/ctwa": {
      "post": {
        "description": "Messaging Ads. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates a click-to-WhatsApp ad that spends the given budget. Deprecated by the ad platform integration. Deprecated: use POST /apis/v1/ads/messaging with `destination: whatsapp`. This endpoint stays available for back-compat; no removal planned. Creates one or more Click-to-WhatsApp (CTWA) ads on Meta under a single campaign and ad set. When tapped, each ad opens a WhatsApp conversation with the business attached to the supplied Facebook Page.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_ctwa",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_757082720485182",
                "budgetAmount": 2.61,
                "budgetType": "daily",
                "connectionId": "adc_7f3k2m9q",
                "creatives": [
                  {
                    "objectStoryId": "811889972008357_123456789"
                  }
                ],
                "name": "WhatsApp existing post",
                "status": "PAUSED"
              },
              "schema": {
                "additionalProperties": true,
                "description": "Besides the `required` list, the request must use EXACTLY ONE of these shapes: Single-creative: `headline`, `body`, and one of `imageUrl` / `video`, OR `platformPostId` / `objectStoryId` to reuse an organic post.",
                "properties": {
                  "adAccountId": {
                    "description": "Meta ad account ID, e.g. `act_123456789`.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "adSetId": {
                    "description": "Attaches the creatives to this EXISTING messaging ad set instead of building a campaign, so the ad set keeps its learning phase. Its `destination_type` must match the ad's destination. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "adSetName": {
                    "description": "Exact name for the ad set this request provisions. Omitted keeps ` - Ad Set`. Ignored with `adSetId`.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "adSetStatus": {
                    "description": "Ad-set-level status, same semantics as `POST /apis/v1/ads/create`. Sets the new ad set's switch alone and overrides `status` for it.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "adStatus": {
                    "description": "Request-side publish switch for `adStatus` on ad creation endpoints only (`status`, `campaignStatus` and `adSetStatus` carry their own inline ACTIVE/PAUSED enum there; the status-update endpoints are a separate lowercase `active`/`paused`…",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "advantageAudience": {
                    "description": "Meta's Advantage+ audience expansion. `0` (default) keeps targeting strict; `1` lets Meta expand beyond the supplied targeting when its delivery system finds better matches. Always sent on CREATE (Meta requires it).",
                    "enum": [
                      0,
                      1
                    ],
                    "type": "integer"
                  },
                  "ageMax": {
                    "maximum": 65,
                    "minimum": 13,
                    "type": "integer"
                  },
                  "ageMin": {
                    "maximum": 65,
                    "minimum": 13,
                    "type": "integer"
                  },
                  "audienceExclude": {
                    "description": "Custom or lookalike audience ids to exclude. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "audienceId": {
                    "description": "Custom audience ID to target. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "audienceInclude": {
                    "description": "Custom or lookalike audience ids to include. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "behaviors": {
                    "description": "Behavior ids from /apis/v1/ads/targeting/search?dimension=behavior. Meta: each dimension is its own flexible_spec entry (OR within, AND across). TikTok: video/creator interaction categories, sent as the ad group's actions.",
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "bidAmount": {
                    "description": "Whole currency units (e.g. `5` = $5.00 on a USD account). Required when `bidStrategy` is `LOWEST_COST_WITH_BID_CAP` or `COST_CAP`; rejected otherwise.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "bidStrategy": {
                    "description": "Meta bid strategy applied to the shared ad set. Defaults to `LOWEST_COST_WITHOUT_CAP` (auto-bid) when omitted. `LOWEST_COST_WITH_BID_CAP` and `COST_CAP` require `bidAmount`. `LOWEST_COST_WITH_MIN_ROAS` requires `roasAverageFloor`.",
                    "enum": [
                      "LOWEST_COST_WITHOUT_CAP",
                      "LOWEST_COST_WITH_BID_CAP",
                      "COST_CAP",
                      "LOWEST_COST_WITH_MIN_ROAS"
                    ],
                    "type": "string"
                  },
                  "body": {
                    "description": "Primary text shown above the image / video. Single-creative shape only. Mutually exclusive with `creatives[]`.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "budgetAmount": {
                    "description": "Budget amount in the ad account's currency major units (e.g. dollars for USD, not cents). Must be > 0. Required unless `adSetId` is set (the ad set owns it) or `existingCampaignId` names a campaign with a campaign budget.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "budgetLevel": {
                    "description": "Where the budget lives. `adset` (default) puts it on the new ad set. `campaign` creates an Advantage campaign budget (CBO): the budget and bid strategy sit on the campaign and the ad set inherits them, same as POST /apis/v1/ads/create.",
                    "enum": [
                      "adset",
                      "campaign"
                    ],
                    "type": "string"
                  },
                  "budgetType": {
                    "description": "Required unless `adSetId` is set or `existingCampaignId` names a campaign with a campaign budget. `lifetime` requires `endDate`.",
                    "enum": [
                      "daily",
                      "lifetime"
                    ],
                    "type": "string"
                  },
                  "campaignName": {
                    "description": "Exact name for the campaign this request provisions. Omitted keeps ` - Campaign`. Ignored with `adSetId` (the ad set already has a campaign).",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "campaignStatus": {
                    "description": "Campaign-level status, same semantics as `POST /apis/v1/ads/create`. Defaults to `status`. `PAUSED`: holds the new campaign off while the ad set and ads switch on (one resume call brings the whole hierarchy live).",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "carouselCards": {
                    "description": "Messaging and CTWA only (a 400 on POST /apis/v1/ads/call). A hand-built carousel of 2-10 image cards, sent to Meta in the given order as `link_data.child_attachments`.",
                    "items": {
                      "description": "One card of a messaging ad carousel (Meta link_data.child_attachments). Every card opens the same conversation, so a card has no link of its own.",
                      "properties": {
                        "callToAction": {
                          "description": "Optional. Must equal the destination's messaging call to action (WHATSAPP_MESSAGE for whatsapp, MESSAGE_PAGE for messenger, INSTAGRAM_MESSAGE for instagram_direct; with `destinations` the first one listed).",
                          "type": "string"
                        },
                        "description": {
                          "description": "Card description, under the title.",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "headline": {
                          "description": "Card title (Meta name).",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Card image. Uploaded to the ad account and sent as the card image_hash (by URL on validateOnly).",
                          "format": "uri",
                          "type": "string"
                        },
                        "linkUrl": {
                          "description": "Not accepted: a 400. The card tap opens the conversation, not a website.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "imageUrl"
                      ],
                      "type": "object"
                    },
                    "maxItems": 10,
                    "minItems": 2,
                    "type": "array"
                  },
                  "cities": {
                    "description": "City-level geo targeting for local CTWA campaigns. Each entry maps to Meta's TargetingGeoLocationCity; `key` is Meta's city ID. `radius` and `distance_unit` are coupled: set both or neither.",
                    "items": {
                      "properties": {
                        "distance_unit": {
                          "enum": [
                            "mile",
                            "kilometer"
                          ],
                          "type": "string"
                        },
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "radius": {
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "countries": {
                    "description": "ISO 3166-1 alpha-2 country codes. Defaults to `[\"US\"]` only when no other geo (`cities`, `regions`, `zips`, `metros`, `customLocations`) is supplied.",
                    "items": {
                      "maxLength": 2,
                      "minLength": 2,
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "countryGroups": {
                    "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                    "items": {
                      "enum": [
                        "africa",
                        "asia",
                        "europe",
                        "north_america",
                        "south_america",
                        "oceania",
                        "central_america",
                        "caribbean",
                        "eea",
                        "euro_area",
                        "nafta",
                        "mercosur",
                        "afta",
                        "apec",
                        "gcc",
                        "cisfta",
                        "emerging_markets",
                        "itunes_app_store",
                        "android_free_store",
                        "android_paid_store"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "creativeFeatures": {
                    "additionalProperties": {
                      "enum": [
                        "OPT_IN",
                        "OPT_OUT"
                      ],
                      "type": "string"
                    },
                    "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                    "type": "object"
                  },
                  "creatives": {
                    "description": "Multi-creative shape: N CTWA ads under one campaign + one ad set, sharing budget and targeting. Fresh and existing creatives can be mixed. Each entry supplies headline, body, and image/video, or a platformPostId or objectStoryId reference.",
                    "items": {
                      "description": "Supply headline, body, and image/video; or body and carouselCards (no headline); or exactly one existing post reference. References cannot be combined with headline, body, imageUrl, video or carouselCards; welcomeMessage works on all three.",
                      "properties": {
                        "body": {
                          "description": "Primary text shown above the image / video.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "carouselCards": {
                          "description": "A 2-10 card carousel for this entry instead of `imageUrl` / `video`; `body` is required. Same rules as the top-level `carouselCards`. Carousel and single-media entries can be mixed on one ad set.",
                          "items": {
                            "description": "One card of a messaging ad carousel (Meta link_data.child_attachments). Every card opens the same conversation, so a card has no link of its own.",
                            "properties": {
                              "callToAction": {
                                "description": "Optional. Must equal the destination's messaging call to action (WHATSAPP_MESSAGE for whatsapp, MESSAGE_PAGE for messenger, INSTAGRAM_MESSAGE for instagram_direct; with `destinations` the first one listed).",
                                "type": "string"
                              },
                              "description": {
                                "description": "Card description, under the title.",
                                "maxLength": 255,
                                "type": "string"
                              },
                              "headline": {
                                "description": "Card title (Meta name).",
                                "maxLength": 255,
                                "type": "string"
                              },
                              "imageUrl": {
                                "description": "Card image. Uploaded to the ad account and sent as the card image_hash (by URL on validateOnly).",
                                "format": "uri",
                                "type": "string"
                              },
                              "linkUrl": {
                                "description": "Not accepted: a 400. The card tap opens the conversation, not a website.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "imageUrl"
                            ],
                            "type": "object"
                          },
                          "maxItems": 10,
                          "minItems": 2,
                          "type": "array"
                        },
                        "creativeFeatures": {
                          "additionalProperties": {
                            "enum": [
                              "OPT_IN",
                              "OPT_OUT"
                            ],
                            "type": "string"
                          },
                          "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                          "type": "object"
                        },
                        "existingPostId": {
                          "description": "Alias of platformPostId, kept for existing callers. Sending both with different values is a 400.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "headline": {
                          "maxLength": 255,
                          "minLength": 1,
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Image asset. Mutually exclusive with this entry's `video`. Required if neither `video` nor an existing post reference is supplied.",
                          "format": "uri",
                          "type": "string"
                        },
                        "objectStoryId": {
                          "description": "Messaging and CTWA only. Raw Facebook pageId_postId reference, used as object_story_id even with an Instagram account. Mutually exclusive with platformPostId and fresh creative fields.",
                          "pattern": "^\\d+_\\d+$",
                          "type": "string"
                        },
                        "platformPostId": {
                          "description": "Messaging and CTWA only. Platform post or reel ID, the same input boostPost takes as platformPostId. Mutually exclusive with objectStoryId and fresh creative fields. Facebook IDs become object_story_id.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "video": {
                          "description": "Video creative. Mutually exclusive with this entry's `imageUrl`. Required if neither `imageUrl` nor an existing post reference is supplied.",
                          "properties": {
                            "id": {
                              "description": "Reuse a video already uploaded to this ad account (list them with GET /apis/v1/ads/videos) instead of re-uploading. Wins over `url`. Provide either `url` or `id`.",
                              "type": "string"
                            },
                            "thumbnailUrl": {
                              "description": "OPTIONAL: when omitted, the poster is auto-generated from Meta's own preferred video thumbnail. When Meta produces no candidate the request fails with a 502 platform_error (reason: video_thumbnail_unavailable).",
                              "format": "uri",
                              "type": "string"
                            },
                            "url": {
                              "description": "Public URL of the video to upload. Provide either `url` or `id`.",
                              "format": "uri",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "welcomeMessage": {
                          "description": "Custom chat welcome message for this entry: `text` plus exactly one of `prefillText` or `quickReplies` (400 otherwise). Same shape as the top-level `welcomeMessage` of the single-creative shape.",
                          "properties": {
                            "prefillText": {
                              "description": "Message put into the user's text input, ready to send. Replaces Meta's default. Exactly one of prefillText or quickReplies.",
                              "minLength": 1,
                              "type": "string"
                            },
                            "quickReplies": {
                              "description": "Tappable chips under the greeting instead of a prefilled message. Exactly one of prefillText or quickReplies.",
                              "items": {
                                "properties": {
                                  "payload": {
                                    "maxLength": 1000,
                                    "minLength": 1,
                                    "type": "string"
                                  },
                                  "title": {
                                    "description": "Chip label the person taps.",
                                    "maxLength": 20,
                                    "minLength": 1,
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "payload",
                                  "title"
                                ],
                                "type": "object"
                              },
                              "maxItems": 13,
                              "minItems": 1,
                              "type": "array"
                            },
                            "text": {
                              "description": "Greeting shown when the chat opens. Replaces Meta's default.",
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "currency": {
                    "description": "ISO 4217 currency code matching the ad account's currency (e.g. `USD`).",
                    "maxLength": 3,
                    "minLength": 3,
                    "type": "string"
                  },
                  "customLocations": {
                    "description": "Point-radius geo (Meta `geo_locations.custom_locations`). Use for targeting a radius around a specific lat/long when no Meta city/region key fits. `distanceUnit` is required.",
                    "items": {
                      "properties": {
                        "address": {
                          "type": "string"
                        },
                        "distanceUnit": {
                          "enum": [
                            "mile",
                            "kilometer"
                          ],
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        },
                        "name": {
                          "type": "string"
                        },
                        "radius": {
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "distanceUnit",
                        "latitude",
                        "longitude",
                        "radius"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "description": {
                    "description": "Link description, independent of `headline` and `body`: Meta's `link_data.description`, `video_data.link_description` on video, and the shared description of a `placementAssets` feed.",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "dsaBeneficiary": {
                    "description": "Legal entity that benefits from the ad. Required when targeting EU users (EU DSA, Article 26).",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "dsaPayor": {
                    "description": "Legal entity that pays for the ad. Can differ from `dsaBeneficiary` (for example, an agency paying for a client's ads). Same rules as `dsaBeneficiary`: required for EU targeting unless the ad account has a default payor.",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "endDate": {
                    "description": "ISO 8601 date or date-time, read like `startDate`; a date-only value ends at 23:59:59 local. Required when `budgetType` is `lifetime`.",
                    "type": "string"
                  },
                  "excludedLocations": {
                    "additionalProperties": true,
                    "description": "Geo to exclude, same shape as POST /apis/v1/ads/create (countries, countryGroups, regions, cities, zips, places, neighborhoods, customLocations).",
                    "type": "object"
                  },
                  "existingCampaignId": {
                    "description": "Creates the new messaging ad set (and its ads) under this EXISTING Meta campaign instead of a new one, e.g. several audience ad sets under one campaign. To add ads to an existing ad set instead, use `adSetId`. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "existingPostId": {
                    "description": "Alias of platformPostId, kept for existing callers. Sending both with different values is a 400.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "gender": {
                    "description": "Restrict the audience by gender (Meta `genders`). Omit or send all for everyone; all is ignored in adSetId attach mode. Stored on the ad and read back in `targeting.gender`.",
                    "enum": [
                      "all",
                      "male",
                      "female"
                    ],
                    "type": "string"
                  },
                  "headline": {
                    "description": "Single-creative shape only. Mutually exclusive with `creatives[]`. Required on a single image or video ad (including one built with `placementAssets`); not used by a `carouselCards` ad and not accepted with an existing post reference.",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "imageUrl": {
                    "description": "Image asset for single-creative shape. Mutually exclusive with `video` and with `creatives[]`. Required on the single-creative shape if neither `video` nor an existing post reference is supplied.",
                    "format": "uri",
                    "type": "string"
                  },
                  "incomeTier": {
                    "description": "Normalized household-income tier, same as POST /apis/v1/ads/create. Incompatible with housing, employment and credit specialAdCategories.",
                    "enum": [
                      "top_5",
                      "top_10",
                      "top_10_25",
                      "top_25_50"
                    ],
                    "type": "string"
                  },
                  "interests": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "languages": {
                    "description": "Audience languages (Meta `locales`). A bare ISO 639-1 code targets all regional variants (\"en\" = all English), a region-qualified code a specific one (\"en_GB\", \"pt_BR\"); unknown codes are rejected.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "metros": {
                    "description": "DMA / metro-area geo targeting. `key` is Meta's metro id (e.g. `DMA:807`).",
                    "items": {
                      "properties": {
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "name": {
                    "description": "Ad display name. Used to derive campaign / ad set names. On the multi-creative shape, each ad's Meta name gets a \" #N\" suffix (1-indexed) so Ads Manager shows them as a numbered batch.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "neighborhoods": {
                    "description": "Meta neighborhood keys (from GET /apis/v1/ads/targeting/search).",
                    "items": {
                      "properties": {
                        "key": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "objectStoryId": {
                    "description": "Messaging and CTWA only. Raw Facebook pageId_postId reference, used as object_story_id even with an Instagram account. Mutually exclusive with platformPostId and fresh creative fields.",
                    "pattern": "^\\d+_\\d+$",
                    "type": "string"
                  },
                  "objective": {
                    "description": "Defaults to `OUTCOME_ENGAGEMENT`. `OUTCOME_SALES` and `OUTCOME_LEADS` require additional account configuration (Dataset linked to the WABA for sales) and may be rejected by Meta if missing.",
                    "enum": [
                      "OUTCOME_ENGAGEMENT",
                      "OUTCOME_SALES",
                      "OUTCOME_LEADS"
                    ],
                    "type": "string"
                  },
                  "optimizeCardOrder": {
                    "description": "Only with `carouselCards` (a 400 without them). Single-creative shape; for `creatives[]` set it per entry. Sets the creative's `link_data.multi_share_optimized`. `false`: keeps the cards in the order given.",
                    "type": "boolean"
                  },
                  "pageId": {
                    "description": "Facebook Page the ad runs as, when the connection was granted several Pages. Defaults to the Page bound to the connection. Any Page granted to the connection is accepted; other ids answer 400 listing the granted Pages.",
                    "type": "string"
                  },
                  "placements": {
                    "description": "Manual ad placements on the shared ad set. Omit for automatic placements.",
                    "properties": {
                      "audienceNetworkPositions": {
                        "items": {
                          "enum": [
                            "classic",
                            "rewarded_video"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "devicePlatforms": {
                        "description": "Restrict by device. Omit to deliver on both mobile and desktop.",
                        "items": {
                          "enum": [
                            "mobile",
                            "desktop"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "facebookPositions": {
                        "items": {
                          "enum": [
                            "feed",
                            "right_hand_column",
                            "marketplace",
                            "story",
                            "search",
                            "instream_video",
                            "facebook_reels",
                            "facebook_reels_overlay",
                            "profile_feed",
                            "notification"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "instagramPositions": {
                        "items": {
                          "enum": [
                            "stream",
                            "story",
                            "explore",
                            "explore_home",
                            "reels",
                            "profile_feed",
                            "ig_search",
                            "profile_reels"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "messengerPositions": {
                        "items": {
                          "enum": [
                            "messenger_home",
                            "sponsored_messages",
                            "story"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "publisherPlatforms": {
                        "description": "Top-level platforms to deliver on. A position field below is only honoured when its parent platform is included here.",
                        "items": {
                          "enum": [
                            "facebook",
                            "instagram",
                            "threads",
                            "messenger",
                            "audience_network",
                            "whatsapp",
                            "meta"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "threadsPositions": {
                        "items": {
                          "enum": [
                            "threads_stream"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "whatsappPositions": {
                        "items": {
                          "enum": [
                            "status"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "places": {
                    "description": "Meta place keys (from GET /apis/v1/ads/targeting/search).",
                    "items": {
                      "properties": {
                        "key": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "platformPostId": {
                    "description": "Messaging and CTWA only. Platform post or reel ID, the same input boostPost takes as platformPostId. Mutually exclusive with objectStoryId and fresh creative fields. Facebook IDs become object_story_id.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "rawTargeting": {
                    "additionalProperties": true,
                    "description": "Meta targeting spec sent as the BASE layer of the ad set's `targeting`, exactly as POST /apis/v1/ads/create does.",
                    "type": "object"
                  },
                  "regionalRegulatedCategories": {
                    "description": "Meta only. Regional regulation categories required when the ad set targets certain countries (e.g.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "regionalRegulationIdentities": {
                    "additionalProperties": {
                      "type": [
                        "string",
                        "integer"
                      ]
                    },
                    "description": "Meta only. Verified identity IDs of the beneficiary and payer for each declared regionalRegulatedCategories value. Ignored when adSetId adds the ad to an existing ad set.",
                    "type": "object"
                  },
                  "regions": {
                    "description": "Region / state-level geo targeting. `key` is Meta's region ID (lookupable via GET /apis/v1/ads/targeting/search?type=region).",
                    "items": {
                      "properties": {
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "roasAverageFloor": {
                    "description": "Decimal ROAS multiplier (e.g. `2.0` = 2.0× ROAS floor). Required when `bidStrategy` is `LOWEST_COST_WITH_MIN_ROAS`; rejected otherwise. Meta enforces its own upper bound server-side.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "savedTargetingId": {
                    "description": "ID of a saved_targeting audience (POST /apis/v1/ads/audiences), expanded as the base targeting. Precedence: savedTargetingId, then `targeting`, then the flat fields. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "specialAdCategories": {
                    "description": "Meta special ad categories on the new campaign.",
                    "items": {
                      "enum": [
                        "HOUSING",
                        "EMPLOYMENT",
                        "CREDIT",
                        "ISSUES_ELECTIONS_POLITICS",
                        "FINANCIAL_PRODUCTS_SERVICES",
                        "ONLINE_GAMBLING_AND_GAMING"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "specialAdCategoryCountry": {
                    "description": "Countries the special ad category applies to. Requires specialAdCategories.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "startDate": {
                    "description": "When the ad set starts delivering. ISO 8601 date or date-time.",
                    "type": "string"
                  },
                  "status": {
                    "description": "Defaults to `ACTIVE`. `PAUSED` pauses only the top-most object this call creates: the new campaign (ad set and ads switched on), or, with `adSetId`, the new ads themselves.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "targeting": {
                    "description": "Normalized, platform-agnostic ad-targeting spec. Every field is optional; an empty object targets the platform's default broadest audience.",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "tracking": {
                    "description": "Ad tracking. Meta, plus `urlTags` on ChatGPT (OpenAI) and `pixelId` on Reddit. Meta: attaches pixel measurement to the ad regardless of the optimization goal (the \"Website events\" tracking row in Ads Manager).",
                    "properties": {
                      "pixelId": {
                        "description": "Meta Pixel ID to attach for offsite-conversion measurement, or the Reddit pixel of the new ad group.",
                        "type": "string"
                      },
                      "urlTags": {
                        "description": "Click-URL params. Meta: stored on the creative as `url_tags` and returned by GET /apis/v1/ads/{adId}/tracking-tags.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "value": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key",
                            "value"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "userDevice": {
                    "description": "Meta `user_device`.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "userOs": {
                    "description": "Meta `user_os`, e.g. [\"iOS_ver_14.0_and_above\"].",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "video": {
                    "description": "Video creative for single-creative shape. Mutually exclusive with `imageUrl` and with `creatives[]`. Required on the single-creative shape if neither `imageUrl` nor an existing post reference is supplied.",
                    "properties": {
                      "id": {
                        "description": "Reuse a video already uploaded to this ad account (list them with GET /apis/v1/ads/videos) instead of re-uploading. Wins over `url`. Provide either `url` or `id`.",
                        "type": "string"
                      },
                      "thumbnailUrl": {
                        "description": "OPTIONAL: when omitted, the poster is auto-generated from Meta's own preferred video thumbnail. When Meta produces no candidate the request fails with a 502 platform_error (reason: video_thumbnail_unavailable).",
                        "format": "uri",
                        "type": "string"
                      },
                      "url": {
                        "description": "Public URL of the video to upload. Provide either `url` or `id`.",
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "welcomeMessage": {
                    "description": "Custom chat welcome message (Meta's `page_welcome_message`, \"Mensaje de bienvenida\" / \"Mensaje predefinido\" in Ads Manager). Single-creative shape only; for `creatives[]` set it per entry.",
                    "properties": {
                      "prefillText": {
                        "description": "Message put into the user's text input, ready to send. Replaces Meta's default (\"Hi! I want more info.\"). Lets one ad steer the opening message toward what it promotes (e.g. a specific product). Exactly one of prefillText or quickReplies.",
                        "minLength": 1,
                        "type": "string"
                      },
                      "quickReplies": {
                        "description": "Tappable chips under the greeting instead of a prefilled message. Exactly one of prefillText or quickReplies. Put your own campaign or ad key in each payload.",
                        "items": {
                          "properties": {
                            "payload": {
                              "maxLength": 1000,
                              "minLength": 1,
                              "type": "string"
                            },
                            "title": {
                              "description": "Chip label the person taps.",
                              "maxLength": 20,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "payload",
                            "title"
                          ],
                          "type": "object"
                        },
                        "maxItems": 13,
                        "minItems": 1,
                        "type": "array"
                      },
                      "text": {
                        "description": "Greeting shown when the chat opens. Replaces Meta's default (\"Hi! Can we help you?\").",
                        "minLength": 1,
                        "type": "string"
                      }
                    },
                    "required": [
                      "text"
                    ],
                    "type": "object"
                  },
                  "whatsappPhoneNumber": {
                    "description": "WhatsApp only. Optional E.164 number already paired with the Facebook Page. Omit to let Meta select the paired number. Sent to the creative CTA and, when creating a new ad set, its promoted_object.",
                    "pattern": "^\\+[1-9]\\d{6,14}$",
                    "type": "string"
                  },
                  "workEmployers": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "workIndustries": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "workPositions": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "zips": {
                    "description": "ZIP / postal-code geo targeting. `key` is the platform's postal id resolved via /apis/v1/ads/targeting/search.",
                    "items": {
                      "properties": {
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  }
                },
                "required": [
                  "adAccountId",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Response returned by `POST /apis/v1/ads/ctwa` when the request used the single-creative shape (top-level headline / body / imageUrl|video). `adType` is the union discriminator.",
                      "properties": {
                        "ad": {
                          "description": "The persisted Ad document.",
                          "type": "object"
                        },
                        "adType": {
                          "enum": [
                            "single"
                          ],
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "warnings": {
                          "description": "Present when Meta created the ad set differently from the request:",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "ad",
                        "adType",
                        "message"
                      ],
                      "type": "object"
                    },
                    {
                      "description": "Response returned by `POST /apis/v1/ads/ctwa` when the request used the multi-creative shape (`creatives[]`). N persisted Ad documents share the returned `platformCampaignId` and `platformAdSetId`. `adType` is the union discriminator.",
                      "properties": {
                        "adType": {
                          "enum": [
                            "multi"
                          ],
                          "type": "string"
                        },
                        "ads": {
                          "description": "The persisted Ad documents (one per creative), all sharing the same `platformCampaignId` and `platformAdSetId`.",
                          "items": {
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "message": {
                          "type": "string"
                        },
                        "platformAdSetId": {
                          "type": "string"
                        },
                        "platformCampaignId": {
                          "type": "string"
                        },
                        "warnings": {
                          "description": "Present when Meta created the ad set differently from the request:",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "adType",
                        "ads",
                        "message",
                        "platformAdSetId",
                        "platformCampaignId"
                      ],
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "CTWA ad(s) created and submitted to Meta for review. Response is a tagged union discriminated by `adType`:"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create CTWA ad (deprecated)",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ctwa_ad@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "119f3b23348bf743c50f030ca68eebb4fe27ad0c970a0431ae115671c11bd5bd"
        },
        "x-aisa-status": "disabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_ctwa",
          "method": "POST",
          "path": "/apis/v1/ads/ctwa"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_ctwa"
      }
    },
    "/apis/v1/ads/dsa-defaults": {
      "get": {
        "description": "Ad Accounts. Read only. Shows the default EU DSA beneficiary and payor set on a Meta ad account. Returns the default DSA beneficiary and payor currently set on a Meta ad account, whether they were set via `PATCH /apis/v1/ads/accounts` or in Meta Ads Manager. Fields are omitted when no default is configured. Meta accounts only.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_dsa_defaults",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account ID (act_...)",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "dsaDefaults": {
                      "properties": {
                        "beneficiary": {
                          "type": "string"
                        },
                        "payor": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Current DSA defaults (empty object when none are set)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get ad account DSA defaults",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_dsa_defaults@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "d908bd159242460bc7ab3093015612147b25299e43db2832047cd6cee107e67c"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_dsa_defaults",
          "method": "GET",
          "path": "/apis/v1/ads/dsa-defaults"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_dsa_defaults"
      }
    },
    "/apis/v1/ads/dsa-recommendations": {
      "get": {
        "description": "Ad Accounts. Read only. Suggests beneficiary and payor names for a Meta ad account's EU DSA disclosures, for your user to pick from. Returns Meta's suggested beneficiary/payor names for an ad account, derived by Meta from the account's recent activity. Useful for prefilling `dsaBeneficiary`/`dsaPayor` inputs, or the defaults sent to `PATCH /apis/v1/ads/accounts`, in your own UI. Meta returns a single flat list.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_dsa_recommendations",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account ID (act_...)",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "recommendations": {
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Suggested DSA strings (may be empty when Meta has no recommendations)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get DSA recommendations",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_dsa_recommendations@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "97ee660076ebe61b850e789d75d2c8918886054b7c041d3e971cc86a17226b46"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_dsa_recommendations",
          "method": "GET",
          "path": "/apis/v1/ads/dsa-recommendations"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_dsa_recommendations"
      }
    },
    "/apis/v1/ads/high-demand-periods": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the scheduled budget increases set on a Meta campaign or ad set. Scheduled budget increases (Meta's budget-scheduling API). The Graph edge lives on the campaign and ad-set nodes only, so exactly one of `campaignId` / `adSetId` (platform ids) is required. Rows returned verbatim (budget_value, budget_value_type, time window, recurrence).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_high_demand_periods",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform campaign id. Exactly one of campaignId / adSetId. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Platform ad set id. Exactly one of campaignId / adSetId. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "adSetId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Rows per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "description": "Raw Meta high-demand-period row.",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "objectId": {
                      "description": "The campaign / ad set id the schedules belong to.",
                      "type": "string"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Budget schedules (raw Meta shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List high-demand periods",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_high_demand_periods@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "530eaf431f1b31dd2c8a217f04dd8c63771144a3b1af4010e06801c3318810ce"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_high_demand_periods",
          "method": "GET",
          "path": "/apis/v1/ads/high-demand-periods"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_high_demand_periods"
      },
      "post": {
        "description": "Ad Accounts. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Schedules a budget increase for a period. Schedules a temporary budget increase on a Meta campaign or ad set for a busy period, like Black Friday or a launch. Same target rule as the GET: exactly one of `campaignId` / `adSetId`. ### Meta constraints `timeStart` / `timeEnd` must fall on a 15-minute boundary. A campaign cannot mix `ABSOLUTE` and `MULTIPLIER` across its schedules.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_high_demand_periods",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "budgetValue": 10,
                "budgetValueType": "ABSOLUTE",
                "connectionId": "adc_7f3k2m9q",
                "timeEnd": 10,
                "timeStart": 10
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adSetId": {
                    "description": "Platform ad set id. Exactly one of campaignId / adSetId. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "budgetValue": {
                    "description": "With ABSOLUTE, a budget in the ad account's currency in WHOLE units (50 = $50.00). With MULTIPLIER, a factor of the existing budget (2 = double it) and NOT a currency amount.",
                    "type": "number"
                  },
                  "budgetValueType": {
                    "enum": [
                      "ABSOLUTE",
                      "MULTIPLIER"
                    ],
                    "type": "string"
                  },
                  "campaignId": {
                    "description": "Platform campaign id. Exactly one of campaignId / adSetId. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "currency": {
                    "description": "Ad account currency, for the ABSOLUTE minor-unit conversion. Ignored for MULTIPLIER.",
                    "type": "string"
                  },
                  "recurrenceType": {
                    "enum": [
                      "ONE_TIME",
                      "WEEKLY",
                      "MONTHLY"
                    ],
                    "type": "string"
                  },
                  "timeEnd": {
                    "description": "Unix seconds, on a 15-minute boundary and after timeStart.",
                    "type": "integer"
                  },
                  "timeStart": {
                    "description": "Unix seconds, on a 15-minute boundary (:00, :15, :30, :45).",
                    "type": "integer"
                  }
                },
                "required": [
                  "budgetValue",
                  "budgetValueType",
                  "timeEnd",
                  "timeStart"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "id": {
                      "description": "Meta budget schedule id.",
                      "type": "string"
                    },
                    "objectId": {
                      "description": "The campaign / ad set the schedule was attached to.",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Budget schedule created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Schedule a budget increase",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_high_demand_period@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "9ea16c64c51adc3b5d7fb47ed26e679ce4ee191b31c1d746969abafc1cfc0fa2"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_high_demand_periods",
          "method": "POST",
          "path": "/apis/v1/ads/high-demand-periods"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_high_demand_periods"
      }
    },
    "/apis/v1/ads/images": {
      "get": {
        "description": "Ad Creatives. Read only. Lists the images in a Meta ad account's library so you can reuse one in a creative. Lists the ad account's image library (Meta's `/act_X/adimages`), rows returned verbatim. The default projection covers hash, url, name, dimensions and status; `fields` is a raw-passthrough override. Any `hash` here is reusable wherever Meta accepts `image_hash` (e.g. `imageHash` on POST /apis/v1/ads/creatives).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_images",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Graph field override.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Rows per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "description": "Raw Meta ad image row (hash, url, name, width, height, status).",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad images (raw Meta shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Ad image library",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_images@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "d760f22cdaef1a2a32048b382c263bfee5f592dbba62c71bf87f1473fb4a26f8"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_images",
          "method": "GET",
          "path": "/apis/v1/ads/images"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_images"
      },
      "post": {
        "description": "Ad Creatives. Changes the ad account without starting or raising spend; audited. Uploads an image file to a Meta ad account's library, for creatives that are not hosted at a public URL. Returns the image `hash` (Meta's identifier for the asset) and the Meta-hosted `url`, which can be used directly as `imageUrl` on the create endpoints. Max 30 MB decoded.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_images",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "imageBase64": "example"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account id (Meta act_, Google customer id, LinkedIn account id, ...).",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "filename": {
                    "description": "Optional filename shown in Meta's image library. Defaults to ad_image.jpg.",
                    "type": "string"
                  },
                  "imageBase64": {
                    "description": "Raw base64 image bytes, or a full data URL (the data:image/...;base64, prefix is stripped).",
                    "type": "string"
                  }
                },
                "required": [
                  "adAccountId",
                  "imageBase64"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "image": {
                      "properties": {
                        "hash": {
                          "description": "Meta image hash, reusable wherever image_hash is accepted.",
                          "type": "string"
                        },
                        "url": {
                          "description": "Meta-hosted image URL; usable as imageUrl on the create endpoints.",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Image uploaded"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Upload an ad image from base64",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.upload_ad_image@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "bd0b6666a8731160b2ad12ff980b6ba585b10fb522d0014ee223bb63b8a8be8f"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_images",
          "method": "POST",
          "path": "/apis/v1/ads/images"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_images"
      }
    },
    "/apis/v1/ads/insights": {
      "get": {
        "description": "Ad Insights. Read only. Runs a custom performance query against Meta, Google Ads or TikTok and returns the platform's rows as is, for reports the fixed endpoints don't cover. The account's platform picks the contract. ### Meta (facebook/instagram) Forwards caller-chosen `fields`, `breakdowns` and `filtering` to any Meta insights node and returns Meta's rows verbatim. `objectId` (required) selects the node.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_insights",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta only (required there): insights node (act_, campaign id, ad set id or ad id). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "objectId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Google only (required there): the GAQL SELECT statement to run.",
            "in": "query",
            "name": "query",
            "required": false,
            "schema": {
              "maxLength": 10000,
              "type": "string"
            }
          },
          {
            "description": "Google: platform ad account ID (Google customer ID, digits only) when the connection has several Google Ads accounts. TikTok (required there): the advertiser id.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "TikTok only: report_type.",
            "in": "query",
            "name": "reportType",
            "required": false,
            "schema": {
              "default": "BASIC",
              "enum": [
                "BASIC",
                "AUDIENCE"
              ],
              "type": "string"
            }
          },
          {
            "description": "TikTok only (required there): data_level.",
            "in": "query",
            "name": "dataLevel",
            "required": false,
            "schema": {
              "enum": [
                "AUCTION_ADVERTISER",
                "AUCTION_CAMPAIGN",
                "AUCTION_ADGROUP",
                "AUCTION_AD"
              ],
              "type": "string"
            }
          },
          {
            "description": "TikTok only (required there): 1-4 comma-separated TikTok dimensions (e.g. country_code, campaign_id, stat_time_day).",
            "in": "query",
            "name": "dimensions",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "TikTok only (required there): comma-separated TikTok metrics (e.g. reach,impressions,frequency,spend).",
            "in": "query",
            "name": "metrics",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "TikTok only: page number.",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "TikTok only: rows per page.",
            "in": "query",
            "name": "pageSize",
            "required": false,
            "schema": {
              "default": 100,
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Google only: cursor from paging.nextPageToken of the previous page.",
            "in": "query",
            "name": "pageToken",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Row granularity",
            "in": "query",
            "name": "level",
            "required": false,
            "schema": {
              "enum": [
                "ad",
                "adset",
                "campaign",
                "account"
              ],
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Graph insights fields (e.g. spend,impressions,frequency,website_purchase_roas). Omitted = Meta's default set.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only: comma-separated Graph breakdowns (e.g. age,gender or publisher_platform). Returns 400 on TikTok (add the breakdown to dimensions with reportType=AUDIENCE, e.g.",
            "in": "query",
            "name": "breakdowns",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Graph action breakdowns; segments the actions[] arrays in each row.",
            "in": "query",
            "name": "actionBreakdowns",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Meta attribution windows. Action values are returned keyed per window.",
            "in": "query",
            "name": "actionAttributionWindows",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "When actions are counted: impression, conversion or mixed.",
            "in": "query",
            "name": "actionReportTime",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Use the ad sets' own attribution settings for action counting.",
            "in": "query",
            "name": "useUnifiedAttributionSetting",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "JSON array of filter objects: [{\"field\", \"operator\", \"value\"}]. Applied server-side by Meta or TikTok (TikTok fields e.g. campaign_ids, adgroup_ids, ad_ids).",
            "in": "query",
            "name": "filtering",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta date_preset (e.g. last_7d, last_30d, this_month). Mutually exclusive with fromDate/toDate.",
            "in": "query",
            "name": "datePreset",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Start of range (YYYY-MM-DD); requires toDate. Required on TikTok.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End of range (YYYY-MM-DD); requires fromDate.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Days per row (1-90), monthly, or all_days.",
            "in": "query",
            "name": "timeIncrement",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Rows per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 500,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "description": "TikTok responses only: the advertiser queried.",
                      "type": "string"
                    },
                    "customerId": {
                      "description": "Google responses only: the customer the query ran against.",
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "description": "Raw platform row. Meta: keys are the requested Graph fields plus date_start/date_stop. Google: nested GAQL resources in camelCase, int64 counters as strings. TikTok: { dimensions, metrics } with metric values as strings.",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "fieldMask": {
                      "description": "Google responses only: the selected fields echoed by Google.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "objectId": {
                      "description": "Meta responses only.",
                      "type": "string"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Meta cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "nextPageToken": {
                          "description": "Google cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "page": {
                          "description": "TikTok only: current page.",
                          "type": "integer"
                        },
                        "pageSize": {
                          "description": "TikTok only.",
                          "type": "integer"
                        },
                        "totalPages": {
                          "description": "TikTok only.",
                          "type": "integer"
                        },
                        "totalRows": {
                          "description": "TikTok only.",
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Insight rows (raw platform shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Flexible live insights query",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.query_ad_insights@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "65067fee636cb8e46c40426990875c28ea8c451a7a8ac48249f4676ab678a07d"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_insights",
          "method": "GET",
          "path": "/apis/v1/ads/insights"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_insights"
      }
    },
    "/apis/v1/ads/insights/reports": {
      "post": {
        "description": "Ad Insights. Read only. Starts a background Meta insights report for long date ranges or large accounts where a live query would be too slow. Same query surface as GET /apis/v1/ads/insights, but in the JSON body; Meta processes the report server-side, which is the right choice for long ranges or large accounts where the sync query is slow or rate-limited.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_insights_reports",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "objectId": "1234567890"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "actionAttributionWindows": {
                    "description": "Meta attribution windows (e.g. [\"7d_click\", \"1d_view\"]). Action values are returned keyed per window.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "actionBreakdowns": {
                    "description": "Comma-separated Graph action breakdowns (e.g. action_type,action_destination). Pass `none` to clear Meta's default action_type breakdown, needed for some non-action breakdowns such as instagram_ads_follow_type.",
                    "type": "string"
                  },
                  "actionReportTime": {
                    "description": "When actions are counted: impression, conversion or mixed.",
                    "type": "string"
                  },
                  "breakdowns": {
                    "description": "Comma-separated Graph breakdowns.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "datePreset": {
                    "description": "Mutually exclusive with fromDate/toDate.",
                    "type": "string"
                  },
                  "fields": {
                    "description": "Comma-separated Graph insights fields.",
                    "type": "string"
                  },
                  "filtering": {
                    "description": "Meta filter objects, applied server-side.",
                    "items": {
                      "properties": {
                        "field": {
                          "type": "string"
                        },
                        "operator": {
                          "type": "string"
                        },
                        "value": {}
                      },
                      "required": [
                        "field",
                        "operator"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "fromDate": {
                    "format": "date",
                    "type": "string"
                  },
                  "level": {
                    "enum": [
                      "ad",
                      "adset",
                      "campaign",
                      "account"
                    ],
                    "type": "string"
                  },
                  "objectId": {
                    "description": "Meta insights node: act_, campaign id, ad set id or ad id. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "timeIncrement": {
                    "oneOf": [
                      {
                        "maximum": 90,
                        "minimum": 1,
                        "type": "integer"
                      },
                      {
                        "enum": [
                          "monthly",
                          "all_days"
                        ],
                        "type": "string"
                      }
                    ]
                  },
                  "toDate": {
                    "format": "date",
                    "type": "string"
                  },
                  "useUnifiedAttributionSetting": {
                    "description": "Use the ad sets' own attribution settings for action counting.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "objectId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "reportRunId": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Report run submitted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Submit async insights report",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_insights_report@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "640b8bef52a962f83ee41f6c9cf9664fcea207df231c92d1b1639581d554ec74"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_insights_reports",
          "method": "POST",
          "path": "/apis/v1/ads/insights/reports"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_insights_reports"
      }
    },
    "/apis/v1/ads/insights/reports/{reportRunId}": {
      "get": {
        "description": "Ad Insights. Read only. Checks progress of a background Meta insights report and returns its results once it has finished. Status and results for a report run created via POST /apis/v1/ads/insights/reports. While the job runs, returns `status` and `percentCompletion`. Once `status` is \"Job Completed\" the response also carries a `data` page, cursor-paginated via `limit` / `after`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_insights_reports_reportrunid",
        "parameters": [
          {
            "in": "path",
            "name": "reportRunId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 500,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "description": "Present only when status is Job Completed.",
                      "items": {
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "dateStart": {
                      "type": "string"
                    },
                    "dateStop": {
                      "type": "string"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    },
                    "percentCompletion": {
                      "type": "integer"
                    },
                    "reportRunId": {
                      "type": "string"
                    },
                    "status": {
                      "description": "Meta async_status: Job Not Started, Job Started, Job Running, Job Completed, Job Failed, Job Skipped.",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Report run status (plus results when completed)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Poll an async insights report run",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_insights_report@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6bd2b7039aeacc74861a1561a951d4954a89b279889ad5b83e4b43ba1654b9ac"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_insights_reports_reportrunid",
          "method": "GET",
          "path": "/apis/v1/ads/insights/reports/{reportRunId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_insights_reports_reportrunid"
      }
    },
    "/apis/v1/ads/instagram-accounts": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the Instagram accounts a Meta ad connection can run ads as, so you can pick the identity for a new ad. Discovers identities through connected_instagram_accounts, Page linkage and Page-backed identities, with a best-effort business fallback. Business permission errors do not fail discovery.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_instagram_accounts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account ID including the act_ prefix.",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "pattern": "^act_[0-9]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "accounts": {
                      "items": {
                        "properties": {
                          "igUserId": {
                            "description": "Instagram identity ID.",
                            "type": "string"
                          },
                          "isPageBacked": {
                            "description": "Whether this is a Page-backed Instagram identity.",
                            "type": "boolean"
                          },
                          "profilePictureUrl": {
                            "description": "Profile picture URL when available.",
                            "type": "string"
                          },
                          "source": {
                            "description": "Discovery source; Page linkage also uses page_backed.",
                            "enum": [
                              "ad_account",
                              "page_backed",
                              "business"
                            ],
                            "type": "string"
                          },
                          "username": {
                            "description": "Instagram username; empty when Meta does not expose it.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "igUserId",
                          "isPageBacked",
                          "source",
                          "username"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "pages": {
                      "items": {
                        "properties": {
                          "connectedInstagramAccount": {
                            "properties": {
                              "igUserId": {
                                "description": "Instagram identity ID.",
                                "type": "string"
                              },
                              "profilePictureUrl": {
                                "description": "Profile picture URL when available.",
                                "type": "string"
                              },
                              "username": {
                                "description": "Instagram username; empty when Meta does not expose it.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "igUserId",
                              "username"
                            ],
                            "type": "object"
                          },
                          "instagramBusinessAccount": {
                            "properties": {
                              "igUserId": {
                                "description": "Instagram identity ID.",
                                "type": "string"
                              },
                              "profilePictureUrl": {
                                "description": "Profile picture URL when available.",
                                "type": "string"
                              },
                              "username": {
                                "description": "Instagram username; empty when Meta does not expose it.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "igUserId",
                              "username"
                            ],
                            "type": "object"
                          },
                          "name": {
                            "description": "Facebook Page name.",
                            "type": "string"
                          },
                          "pageId": {
                            "description": "Facebook Page ID.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "name",
                          "pageId"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "resolved": {
                      "properties": {
                        "igUserId": {
                          "description": "Instagram identity selected by the shared ad-creation resolver.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "pageId": {
                          "description": "Page selected by the shared ad-creation resolver.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "source": {
                          "description": "Discovery source of the resolved identity; null when absent from discovery.",
                          "enum": [
                            "ad_account",
                            "page_backed",
                            "business",
                            null
                          ],
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "igUserId",
                        "pageId",
                        "source"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "accounts",
                    "pages",
                    "resolved"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Instagram identities and Page linkage."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List Instagram ad identities",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ads_instagram_accounts@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "d4edb5c44134dbb798167d5fed69bd0003d9e4571d0c5bcefb3323b8b85839ea"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_instagram_accounts",
          "method": "GET",
          "path": "/apis/v1/ads/instagram-accounts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_instagram_accounts"
      }
    },
    "/apis/v1/ads/instagram-posts": {
      "get": {
        "description": "Ad Accounts. Read only. Lists posts from the Instagram account a Meta ad connection can reach, so you can boost one as an ad. An existing Instagram post can be boosted this way without connecting the Instagram account separately. Each `posts[].id` is the existing-post id to send as `platformPostId` when creating the ad; Meta turns it into `source_instagram_media_id` on the creative.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_instagram_posts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account ID including the act_ prefix. Narrows identity resolution to the Instagram accounts reachable from this ad account.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^act_[0-9]+$",
              "type": "string"
            }
          },
          {
            "description": "Instagram identity to list. Must be one this connection can reach, otherwise the request is rejected with a 400.",
            "in": "query",
            "name": "igUserId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Number of posts to return per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Opaque Meta cursor from a previous response's paging.after.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "igUserId": {
                      "description": "Instagram identity the posts belong to.",
                      "type": "string"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page, or null when this is the last one.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "after"
                      ],
                      "type": "object"
                    },
                    "posts": {
                      "items": {
                        "properties": {
                          "caption": {
                            "description": "Caption, when the media has one.",
                            "type": "string"
                          },
                          "id": {
                            "description": "Instagram media ID. Pass this as the existing-post id when creating an ad.",
                            "type": "string"
                          },
                          "mediaType": {
                            "description": "Meta media_type, e.g. IMAGE, VIDEO or CAROUSEL_ALBUM.",
                            "type": "string"
                          },
                          "mediaUrl": {
                            "description": "Media URL. Meta omits it for some media types.",
                            "type": "string"
                          },
                          "permalink": {
                            "description": "Public Instagram permalink.",
                            "type": "string"
                          },
                          "thumbnailUrl": {
                            "description": "Thumbnail URL. Present for VIDEO, where mediaUrl may be absent.",
                            "type": "string"
                          },
                          "timestamp": {
                            "description": "Publish time as Meta reports it.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "mediaType",
                          "timestamp"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "username": {
                      "description": "Instagram username; empty when Meta does not expose it.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "igUserId",
                    "paging",
                    "posts",
                    "username"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Instagram posts available to boost."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List Instagram posts to boost",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ads_instagram_posts@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "430c13b56d42cbaf1e96b44db5e469817ab2d3f1ace30721dc01eeea0da9f439"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_instagram_posts",
          "method": "GET",
          "path": "/apis/v1/ads/instagram-posts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_instagram_posts"
      }
    },
    "/apis/v1/ads/interests": {
      "get": {
        "description": "Ad Targeting. Read only. Deprecated by the ad platform integration. Deprecated alias for `GET /apis/v1/ads/targeting/search?dimension=interest`. Kept for backward compatibility, it returns the legacy `{ interests: [...] }` shape rather than the normalized `{ results: [...] }`. New integrations should use `GET /apis/v1/ads/targeting/search` with `dimension=interest`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_interests",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "搜索查询",
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "interests": {
                      "items": {
                        "properties": {
                          "category": {
                            "type": "string"
                          },
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Matching interests"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Search targeting interests",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.search_ad_interests@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "c1ba588417229b2018fbe5400649936e39f224a3caa542d0806818a9a053d66f"
        },
        "x-aisa-status": "disabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_interests",
          "method": "GET",
          "path": "/apis/v1/ads/interests"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_interests"
      }
    },
    "/apis/v1/ads/ios-fourteen-campaign-limits": {
      "get": {
        "description": "Ad Accounts. Read only. Shows Meta's iOS 14 campaign limits for an app on an ad account (it does not confirm the app is set up for iOS promotion). applicationId is sent as Meta app_id. This read does not establish that the application is configured for iOS promotion.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_ios_fourteen_campaign_limits",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account ID including the act_ prefix.",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "pattern": "^act_[0-9]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta application ID from advertisable-applications.",
            "in": "query",
            "name": "applicationId",
            "required": true,
            "schema": {
              "pattern": "^[0-9]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "limits": {
                      "properties": {
                        "campaignGroupLimit": {
                          "description": "Campaign group limit reported by Meta.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "campaignGroupLimitsDetails": {
                          "description": "Campaign group limit details returned by Meta.",
                          "items": {},
                          "type": "array"
                        },
                        "campaignLimit": {
                          "description": "Campaign limit reported by Meta.",
                          "type": [
                            "number",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "limits"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Application campaign limits."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get iOS 14 campaign limits",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ios_fourteen_campaign_limits@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6feb216b0e3e58bb5727cd3346f9a6a6458fc240a453c40b3d604de94f3e5dd6"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_ios_fourteen_campaign_limits",
          "method": "GET",
          "path": "/apis/v1/ads/ios-fourteen-campaign-limits"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_ios_fourteen_campaign_limits"
      }
    },
    "/apis/v1/ads/keywords": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists the keywords and negative keywords in your Google Search ad groups. Returns the Google Search keyword criteria (positive and negative) synced from connected Google Ads accounts, one row per ad-group keyword. Campaign-level negative keywords are not included; only ad-group-level criteria are. ### Freshness\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_keywords",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Page number (1-based)",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 500,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID). Mirrors the same filter on /apis/v1/ads.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Platform campaign ID Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Platform ad group ID (Google ad group) Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "adSetId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Keyword criterion status",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "active",
                "paused"
              ],
              "type": "string"
            }
          },
          {
            "description": "Accepted in any case.",
            "in": "query",
            "name": "matchType",
            "required": false,
            "schema": {
              "enum": [
                "exact",
                "phrase",
                "broad",
                "unknown"
              ],
              "type": "string"
            }
          },
          {
            "description": "true = negative keywords only, false = positive only. Omit for both.",
            "in": "query",
            "name": "negative",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Case-insensitive substring match on the keyword text",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "keywords": {
                      "items": {
                        "properties": {
                          "adAccountId": {
                            "description": "Google customer ID",
                            "type": "string"
                          },
                          "adSetId": {
                            "description": "Google ad group ID",
                            "type": "string"
                          },
                          "adSetName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "adSetStatus": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignId": {
                            "type": "string"
                          },
                          "campaignName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignStatus": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "description": "Accepted as `keywordId` by PATCH/DELETE /apis/v1/ads/keywords/{keywordId}.",
                            "type": "string"
                          },
                          "keyword": {
                            "type": "string"
                          },
                          "matchType": {
                            "enum": [
                              "exact",
                              "phrase",
                              "broad",
                              "unknown"
                            ],
                            "type": "string"
                          },
                          "metrics": {
                            "description": "Trailing 30-day window. Null on rows synced before the metrics columns existed (re-synced on the keyword's next daily sweep).",
                            "properties": {
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "type": "number"
                              },
                              "cost": {
                                "description": "Account currency, not USD-normalized",
                                "type": "number"
                              },
                              "firstPageCpc": {
                                "description": "Account currency",
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "firstPositionCpc": {
                                "description": "Account currency",
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "windowDays": {
                                "type": "integer"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "negative": {
                            "type": "boolean"
                          },
                          "platform": {
                            "enum": [
                              "google"
                            ],
                            "type": "string"
                          },
                          "platformCriterionId": {
                            "description": "Google ad_group_criterion.criterion_id. Unique only within its ad group (`adSetId`), not across the account.",
                            "type": "string"
                          },
                          "quality": {
                            "description": "Google Quality Score and the three component ratings behind it (`ad_group_criterion.quality_info`). Every field is null until Google has rated the keyword: a keyword with too little traffic is unrated, and negatives are never rated.",
                            "properties": {
                              "adRelevance": {
                                "description": "How closely the ad matches the intent behind the search (`creative_quality_score`).",
                                "enum": [
                                  "BELOW_AVERAGE",
                                  "AVERAGE",
                                  "ABOVE_AVERAGE",
                                  null
                                ],
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "expectedCtr": {
                                "description": "How the click-through rate compares with other ads in the same position (`search_predicted_ctr`).",
                                "enum": [
                                  "BELOW_AVERAGE",
                                  "AVERAGE",
                                  "ABOVE_AVERAGE",
                                  null
                                ],
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "landingPageExperience": {
                                "description": "How relevant and useful the landing page is to people who click (`post_click_quality_score`).",
                                "enum": [
                                  "BELOW_AVERAGE",
                                  "AVERAGE",
                                  "ABOVE_AVERAGE",
                                  null
                                ],
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "score": {
                                "description": "Quality Score, 1-10.",
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              }
                            },
                            "type": "object"
                          },
                          "qualityScore": {
                            "description": "Deprecated, use `quality.score`. Google Quality Score, 1-10. Null when unrated.",
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "resourceName": {
                            "description": "Google resource name, customers/{adAccountId}/adGroupCriteria/{adSetId}~{platformCriterionId}.",
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "active",
                              "paused"
                            ],
                            "type": "string"
                          },
                          "syncedAt": {
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "pagination": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Paginated keywords"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List Search keywords",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_keywords@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "03fbd80cf5fd3963d0c6b127aa224fedb1137f8ac0f9c473b4c69fbbd060ef61"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_keywords",
          "method": "GET",
          "path": "/apis/v1/ads/keywords"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_keywords"
      },
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Adds keywords an ad group bids on. Adds keywords, or negative keywords, to a Google Search ad group without replacing the ones already there. Adds one or more keyword criteria to an existing Google Search ad group, without touching the keywords already there (unlike the whole-set diff on `PUT /apis/v1/ads/{adId}`, `keywords`/`negativeKeywords` in `platformSpecificData`, which replaces the set).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_keywords",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adSetId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "keywords": [
                  "example"
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adSetId": {
                    "description": "Google ad group ID to add the keywords to Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "keywords": {
                    "items": {
                      "anyOf": [
                        {
                          "description": "Keyword text; defaults to BROAD match",
                          "type": "string"
                        },
                        {
                          "properties": {
                            "matchType": {
                              "enum": [
                                "exact",
                                "phrase",
                                "broad"
                              ],
                              "type": "string"
                            },
                            "text": {
                              "maxLength": 80,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "negative": {
                    "default": false,
                    "description": "Add as ad-group-level negatives instead of positive keywords",
                    "type": "boolean"
                  }
                },
                "required": [
                  "adSetId",
                  "keywords"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "keywords": {
                      "items": {
                        "properties": {
                          "adAccountId": {
                            "description": "Google customer ID",
                            "type": "string"
                          },
                          "adSetId": {
                            "description": "Google ad group ID",
                            "type": "string"
                          },
                          "adSetName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "adSetStatus": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignId": {
                            "type": "string"
                          },
                          "campaignName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignStatus": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "description": "Accepted as `keywordId` by PATCH/DELETE /apis/v1/ads/keywords/{keywordId}.",
                            "type": "string"
                          },
                          "keyword": {
                            "type": "string"
                          },
                          "matchType": {
                            "enum": [
                              "exact",
                              "phrase",
                              "broad",
                              "unknown"
                            ],
                            "type": "string"
                          },
                          "metrics": {
                            "description": "Trailing 30-day window. Null on rows synced before the metrics columns existed (re-synced on the keyword's next daily sweep).",
                            "properties": {
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "type": "number"
                              },
                              "cost": {
                                "description": "Account currency, not USD-normalized",
                                "type": "number"
                              },
                              "firstPageCpc": {
                                "description": "Account currency",
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "firstPositionCpc": {
                                "description": "Account currency",
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "windowDays": {
                                "type": "integer"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "negative": {
                            "type": "boolean"
                          },
                          "platform": {
                            "enum": [
                              "google"
                            ],
                            "type": "string"
                          },
                          "platformCriterionId": {
                            "description": "Google ad_group_criterion.criterion_id. Unique only within its ad group (`adSetId`), not across the account.",
                            "type": "string"
                          },
                          "quality": {
                            "description": "Google Quality Score and the three component ratings behind it (`ad_group_criterion.quality_info`). Every field is null until Google has rated the keyword: a keyword with too little traffic is unrated, and negatives are never rated.",
                            "properties": {
                              "adRelevance": {
                                "description": "How closely the ad matches the intent behind the search (`creative_quality_score`).",
                                "enum": [
                                  "BELOW_AVERAGE",
                                  "AVERAGE",
                                  "ABOVE_AVERAGE",
                                  null
                                ],
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "expectedCtr": {
                                "description": "How the click-through rate compares with other ads in the same position (`search_predicted_ctr`).",
                                "enum": [
                                  "BELOW_AVERAGE",
                                  "AVERAGE",
                                  "ABOVE_AVERAGE",
                                  null
                                ],
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "landingPageExperience": {
                                "description": "How relevant and useful the landing page is to people who click (`post_click_quality_score`).",
                                "enum": [
                                  "BELOW_AVERAGE",
                                  "AVERAGE",
                                  "ABOVE_AVERAGE",
                                  null
                                ],
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "score": {
                                "description": "Quality Score, 1-10.",
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              }
                            },
                            "type": "object"
                          },
                          "qualityScore": {
                            "description": "Deprecated, use `quality.score`. Google Quality Score, 1-10. Null when unrated.",
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "resourceName": {
                            "description": "Google resource name, customers/{adAccountId}/adGroupCriteria/{adSetId}~{platformCriterionId}.",
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "active",
                              "paused"
                            ],
                            "type": "string"
                          },
                          "syncedAt": {
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Keywords added"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Add Search ad-group keywords",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.add_ad_keywords@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0cc054a5d2edfdfc2ea0c40ed5110153587e5ba584cd7c846c46319979d14424"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_keywords",
          "method": "POST",
          "path": "/apis/v1/ads/keywords"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_keywords"
      }
    },
    "/apis/v1/ads/keywords/historical-metrics": {
      "post": {
        "description": "Ad Insights. Read only. Gets historical search volume, competition and bid ranges for up to 1,000 keywords from Google Keyword Planner. Google Ads only. Runs Keyword Planner's generateKeywordHistoricalMetrics for up to 1,000 exact keywords: historical search volume, competition and top-of-page bid ranges, plus averageCpcMicros when includeAverageCpc is set.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_keywords_historical_metrics",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "keywords": [
                  "example"
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only).",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "countries": {
                    "description": "ISO 3166-1 alpha-2 country codes. Omitted = worldwide.",
                    "items": {
                      "maxLength": 2,
                      "minLength": 2,
                      "type": "string"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "type": "string"
                  },
                  "includeAdultKeywords": {
                    "type": "boolean"
                  },
                  "includeAverageCpc": {
                    "description": "Adds averageCpcMicros to each row's keywordMetrics.",
                    "type": "boolean"
                  },
                  "keywords": {
                    "items": {
                      "maxLength": 80,
                      "type": "string"
                    },
                    "maxItems": 1000,
                    "minItems": 1,
                    "type": "array"
                  },
                  "languageConstantId": {
                    "default": "1000",
                    "description": "Google languageConstant id (1000 = English).",
                    "type": "string"
                  },
                  "network": {
                    "default": "GOOGLE_SEARCH",
                    "enum": [
                      "GOOGLE_SEARCH",
                      "GOOGLE_SEARCH_AND_PARTNERS"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "keywords"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "aggregateMetricResults": {
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "customerId": {
                      "description": "The customer the request ran against.",
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "description": "Raw KeywordHistoricalMetricsResult: text, closeVariants, keywordMetrics.",
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Historical metric rows (raw Keyword Planner shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get historical keyword metrics",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.generate_keyword_historical_metrics@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "77e48904fd02d106fce97fbb6428ca729a3a0d863f6d11fe2ef3510a25cfded0"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_keywords_historical_metrics",
          "method": "POST",
          "path": "/apis/v1/ads/keywords/historical-metrics"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_keywords_historical_metrics"
      }
    },
    "/apis/v1/ads/keywords/ideas": {
      "post": {
        "description": "Ad Insights. Read only. Suggests new keywords from seed keywords or a website using Google Keyword Planner, with search volume, competition and bid estimates. Google Ads only. Runs Keyword Planner's generateKeywordIdeas from seed keywords, a seed URL, or both, returning idea rows verbatim (avgMonthlySearches, competition, competitionIndex, top-of-page bid micros, monthlySearchVolumes).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_keywords_ideas",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "countries": [
                  "US"
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only).",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "countries": {
                    "description": "ISO 3166-1 alpha-2 country codes. Omitted = worldwide.",
                    "items": {
                      "maxLength": 2,
                      "minLength": 2,
                      "type": "string"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId, kept for existing callers",
                    "type": "string"
                  },
                  "includeAdultKeywords": {
                    "type": "boolean"
                  },
                  "languageConstantId": {
                    "default": "1000",
                    "description": "Google languageConstant id (1000 = English).",
                    "type": "string"
                  },
                  "network": {
                    "default": "GOOGLE_SEARCH",
                    "enum": [
                      "GOOGLE_SEARCH",
                      "GOOGLE_SEARCH_AND_PARTNERS"
                    ],
                    "type": "string"
                  },
                  "pageSize": {
                    "maximum": 10000,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "pageToken": {
                    "description": "Cursor from paging.nextPageToken of the previous page.",
                    "type": "string"
                  },
                  "seedKeywords": {
                    "description": "Seed terms. Provide these, seedUrl, or both.",
                    "items": {
                      "maxLength": 80,
                      "type": "string"
                    },
                    "maxItems": 20,
                    "minItems": 1,
                    "type": "array"
                  },
                  "seedUrl": {
                    "description": "Landing page to mine for ideas. Provide this, seedKeywords, or both.",
                    "format": "uri",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "aggregateMetricResults": {
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "customerId": {
                      "description": "The customer the request ran against.",
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "description": "Raw GenerateKeywordIdeaResult: text + keywordIdeaMetrics.",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "nextPageToken": {
                          "description": "Cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Keyword idea rows (raw Keyword Planner shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Generate keyword ideas",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.generate_keyword_ideas@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "939e0bd626bbe11f58a3ed50a8074857f9ab7b711ddb111a7f3bd7ae4f0dcf2c"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_keywords_ideas",
          "method": "POST",
          "path": "/apis/v1/ads/keywords/ideas"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_keywords_ideas"
      }
    },
    "/apis/v1/ads/keywords/{keywordId}": {
      "delete": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Removes a single keyword or negative keyword from a Google Search ad group. Removes one keyword criterion (positive or negative) from its ad group (M.140).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_keywords_keywordid",
        "parameters": [
          {
            "description": "1234567890~987654321). A bare criterion id is rejected because it is only unique within its ad group.",
            "in": "path",
            "name": "keywordId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adSetId": {
                      "description": "Google ad group ID",
                      "type": "string"
                    },
                    "campaignId": {
                      "description": "Google campaign ID",
                      "type": "string"
                    },
                    "keywordId": {
                      "type": "string"
                    },
                    "platformCriterionId": {
                      "description": "Google ad_group_criterion.criterion_id",
                      "type": "string"
                    },
                    "removed": {
                      "description": "Always true on success",
                      "type": "boolean"
                    },
                    "resourceName": {
                      "description": "Google resource name of the removed criterion",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Keyword removed"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove a Search keyword",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_ad_keyword@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "04a2eefcb2161c8cbfb432072e70292a24aa47234ec97e5a916437397db57236"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_keywords_keywordid",
          "method": "DELETE",
          "path": "/apis/v1/ads/keywords/{keywordId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_keywords_keywordid"
      },
      "patch": {
        "description": "Ad Campaigns. A pause needs ads:write. A change to active turns delivery on: it needs ads:spend and X-Aisa-Confirm: spend. Pauses or re-enables a single Google Search keyword. Changes `ad_group_criterion.status` for one keyword criterion (M.140). Negative keywords have no status on Google and cannot be paused or enabled.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_keywords_keywordid",
        "parameters": [
          {
            "description": "1234567890~987654321). A bare criterion id is rejected because it is only unique within its ad group.",
            "in": "path",
            "name": "keywordId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "status": "active"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "status": {
                    "enum": [
                      "active",
                      "paused"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "status"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "keyword": {
                      "properties": {
                        "adAccountId": {
                          "description": "Google customer ID",
                          "type": "string"
                        },
                        "adSetId": {
                          "description": "Google ad group ID",
                          "type": "string"
                        },
                        "adSetName": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "adSetStatus": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "campaignId": {
                          "type": "string"
                        },
                        "campaignName": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "campaignStatus": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "connectionId": {
                          "description": "The ads connection (adc_...) the object belongs to.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "description": "Accepted as `keywordId` by PATCH/DELETE /apis/v1/ads/keywords/{keywordId}.",
                          "type": "string"
                        },
                        "keyword": {
                          "type": "string"
                        },
                        "matchType": {
                          "enum": [
                            "exact",
                            "phrase",
                            "broad",
                            "unknown"
                          ],
                          "type": "string"
                        },
                        "metrics": {
                          "description": "Trailing 30-day window. Null on rows synced before the metrics columns existed (re-synced on the keyword's next daily sweep).",
                          "properties": {
                            "clicks": {
                              "type": "integer"
                            },
                            "conversions": {
                              "type": "number"
                            },
                            "cost": {
                              "description": "Account currency, not USD-normalized",
                              "type": "number"
                            },
                            "firstPageCpc": {
                              "description": "Account currency",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "firstPositionCpc": {
                              "description": "Account currency",
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "impressions": {
                              "type": "integer"
                            },
                            "windowDays": {
                              "type": "integer"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "negative": {
                          "type": "boolean"
                        },
                        "platform": {
                          "enum": [
                            "google"
                          ],
                          "type": "string"
                        },
                        "platformCriterionId": {
                          "description": "Google ad_group_criterion.criterion_id. Unique only within its ad group (`adSetId`), not across the account.",
                          "type": "string"
                        },
                        "quality": {
                          "description": "Google Quality Score and the three component ratings behind it (`ad_group_criterion.quality_info`). Every field is null until Google has rated the keyword: a keyword with too little traffic is unrated, and negatives are never rated.",
                          "properties": {
                            "adRelevance": {
                              "description": "How closely the ad matches the intent behind the search (`creative_quality_score`).",
                              "enum": [
                                "BELOW_AVERAGE",
                                "AVERAGE",
                                "ABOVE_AVERAGE",
                                null
                              ],
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "expectedCtr": {
                              "description": "How the click-through rate compares with other ads in the same position (`search_predicted_ctr`).",
                              "enum": [
                                "BELOW_AVERAGE",
                                "AVERAGE",
                                "ABOVE_AVERAGE",
                                null
                              ],
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "landingPageExperience": {
                              "description": "How relevant and useful the landing page is to people who click (`post_click_quality_score`).",
                              "enum": [
                                "BELOW_AVERAGE",
                                "AVERAGE",
                                "ABOVE_AVERAGE",
                                null
                              ],
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "score": {
                              "description": "Quality Score, 1-10.",
                              "type": [
                                "integer",
                                "null"
                              ]
                            }
                          },
                          "type": "object"
                        },
                        "qualityScore": {
                          "description": "Deprecated, use `quality.score`. Google Quality Score, 1-10. Null when unrated.",
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "resourceName": {
                          "description": "Google resource name, customers/{adAccountId}/adGroupCriteria/{adSetId}~{platformCriterionId}.",
                          "type": "string"
                        },
                        "status": {
                          "enum": [
                            "active",
                            "paused"
                          ],
                          "type": "string"
                        },
                        "syncedAt": {
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Keyword updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Pause or enable a Search keyword",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_keyword@1",
          "required_scope": "ads:write",
          "scope_rule": "Pausing needs ads:write; turning delivery on needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a3048722bae6a2d712db3581672b0c0890d9957f539d17d9282dcad0012f6a33"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_keywords_keywordid",
          "method": "PATCH",
          "path": "/apis/v1/ads/keywords/{keywordId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_keywords_keywordid"
      }
    },
    "/apis/v1/ads/labels": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the labels used to organise campaigns and ads in an ad account. ### Meta Pass `adAccountId=act_`. Rows are Meta's `/act_X/adlabels` returned verbatim (id, name, created/updated time), paginated with `limit` / `after`. ### Google Ads Pass the numeric customer id as `adAccountId` (optional when the connection has a single customer).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_labels",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_), or the Google Ads customer id (digits only).",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^(act_)?\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Google only. Alias of adAccountId, kept for existing callers.",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Meta only. Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Meta only. Cursor from paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "description": "Meta act_, or the resolved Google customer id",
                      "type": "string"
                    },
                    "cachedAt": {
                      "description": "Google only. When the served list was fetched from Google.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "items": {
                        "oneOf": [
                          {
                            "properties": {
                              "backgroundColor": {
                                "description": "#RRGGBB",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "description": {
                                "description": "Null when empty.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "id": {
                                "description": "Google label id",
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "resourceName": {
                                "type": "string"
                              },
                              "status": {
                                "enum": [
                                  "ENABLED",
                                  "REMOVED",
                                  "UNKNOWN"
                                ],
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          {
                            "description": "Raw Meta ad label row (id, name, created_time, updated_time).",
                            "type": "object"
                          }
                        ]
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted (always null on Google).",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    },
                    "stale": {
                      "description": "Google only. True when Google quota was exhausted and the last cached list was served.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad labels"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List ad labels",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_labels@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "67ef85c7f95d8d0d00f6faeb3ffc07e9208c4a3977a1160b391504f238b836ac"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_labels",
          "method": "GET",
          "path": "/apis/v1/ads/labels"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_labels"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Creates a Google Ads label you can then attach to campaigns, ad groups, ads and keywords to organize and filter them. Attach it to campaigns, ad groups, ads and keywords with `POST /apis/v1/ads/labels/{labelId}/assignments`. Label names are unique per customer; a duplicate is a 400.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_labels",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Google customer id. Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "backgroundColor": {
                    "description": "#RRGGBB. Google picks a color when omitted.",
                    "pattern": "^#[0-9a-fA-F]{6}$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "description": {
                    "maxLength": 200,
                    "type": "string"
                  },
                  "name": {
                    "description": "Trimmed before sending.",
                    "maxLength": 80,
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "id": {
                      "description": "Google label id",
                      "type": "string"
                    },
                    "resourceName": {
                      "description": "customers/{customerId}/labels/{id}",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Label created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a Google Ads label",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_label@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "ba0d8f33e51848f60a33eb6469b2f0e8cce376638835291e02fa4bfc891f92e4"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_labels",
          "method": "POST",
          "path": "/apis/v1/ads/labels"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_labels"
      }
    },
    "/apis/v1/ads/labels/{labelId}": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Deletes a Google Ads label and removes it from everything it was attached to. Google drops it from every campaign, ad group, ad and keyword it was attached to.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_labels_labelid",
        "parameters": [
          {
            "description": "Google label id",
            "in": "path",
            "name": "labelId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google customer id. Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "labelId": {
                      "type": "string"
                    },
                    "removed": {
                      "description": "Always true on success",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Label removed"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove a Google Ads label",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_ad_label@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0f729295ca51df6a88fea5dd3752f8f670087ea9827073e3e73b13f6e009e27b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_labels_labelid",
          "method": "DELETE",
          "path": "/apis/v1/ads/labels/{labelId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_labels_labelid"
      },
      "patch": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Changes a Google Ads label's name, color or description. Only the fields sent are written.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_labels_labelid",
        "parameters": [
          {
            "description": "Google label id",
            "in": "path",
            "name": "labelId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "adAccountId": {
                    "description": "Google customer id. Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "backgroundColor": {
                    "pattern": "^#[0-9a-fA-F]{6}$",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "description": {
                    "description": "Send \"\" to clear it.",
                    "maxLength": 200,
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 80,
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "label": {
                      "properties": {
                        "backgroundColor": {
                          "description": "#RRGGBB",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "description": {
                          "description": "Null when empty.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "description": "Google label id",
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "resourceName": {
                          "type": "string"
                        },
                        "status": {
                          "enum": [
                            "ENABLED",
                            "REMOVED",
                            "UNKNOWN"
                          ],
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Label updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update a Google Ads label",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_label@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1f81b217676d03abe3e5d7b419c79f0830ab687ff24ac5cff7f98ad8860fcf5f"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_labels_labelid",
          "method": "PATCH",
          "path": "/apis/v1/ads/labels/{labelId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_labels_labelid"
      }
    },
    "/apis/v1/ads/labels/{labelId}/assignments": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Removes a Google Ads label from the campaigns, ad groups, ads or keywords you name, skipping any that do not have it. Idempotent; a target without the label is counted in `unchanged`. Fields go in the query string. A JSON body with the same fields is also accepted and, when sent, the query string is ignored.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_labels_labelid_assignments",
        "parameters": [
          {
            "description": "Google label id",
            "in": "path",
            "name": "labelId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Required when the connection has multiple customers.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Google campaign ids. Repeat the parameter or pass a comma-separated list. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignIds",
            "required": false,
            "schema": {
              "items": {
                "pattern": "^\\d+$",
                "type": "string"
              },
              "maxItems": 1000,
              "minItems": 1,
              "type": "array"
            }
          },
          {
            "description": "Google ad group ids. Repeat the parameter or pass a comma-separated list. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "adSetIds",
            "required": false,
            "schema": {
              "items": {
                "pattern": "^\\d+$",
                "type": "string"
              },
              "maxItems": 1000,
              "minItems": 1,
              "type": "array"
            }
          },
          {
            "description": "Google ad group ad ids, {adGroupId}~{adId}. Repeat the parameter or pass a comma-separated list. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "adIds",
            "required": false,
            "schema": {
              "items": {
                "pattern": "^\\d+~\\d+$",
                "type": "string"
              },
              "maxItems": 1000,
              "minItems": 1,
              "type": "array"
            }
          },
          {
            "description": "Google keyword criterion ids, {adGroupId}~{criterionId}. Repeat the parameter or pass a comma-separated list. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "keywordIds",
            "required": false,
            "schema": {
              "items": {
                "pattern": "^\\d+~\\d+$",
                "type": "string"
              },
              "maxItems": 1000,
              "minItems": 1,
              "type": "array"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "detached": {
                      "description": "Links removed by this call",
                      "type": "integer"
                    },
                    "labelId": {
                      "type": "string"
                    },
                    "unchanged": {
                      "description": "Targets that did not carry the label",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Label detached"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Detach a Google Ads label",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.detach_ad_label@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6396a94fa942dca664d97e6f49ff96ed5b228969ca7963d6073ba04d77d586c1"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_labels_labelid_assignments",
          "method": "DELETE",
          "path": "/apis/v1/ads/labels/{labelId}/assignments"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_labels_labelid_assignments"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Attaches a Google Ads label to campaigns, ad groups, ads and keywords in one call, skipping any that already have it. The label goes to campaigns, ad groups, ads and keywords (Google CampaignLabel, AdGroupLabel, AdGroupAdLabel and AdGroupCriterionLabel) in one mutate. Idempotent: a target that already carries the label is counted in `unchanged` instead of failing the call. ### Ids\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_labels_labelid_assignments",
        "parameters": [
          {
            "description": "Google label id",
            "in": "path",
            "name": "labelId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "1234567890",
                "adIds": [
                  "1234567890~1234567890"
                ],
                "connectionId": "adc_7f3k2m9q"
              },
              "schema": {
                "additionalProperties": false,
                "description": "At least one id across the four target lists. Up to 1000 ids per list.",
                "properties": {
                  "adAccountId": {
                    "description": "Google customer id. Required when the connection has multiple customers.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "adIds": {
                    "description": "Google ad group ad ids, {adGroupId}~{adId} Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "pattern": "^\\d+~\\d+$",
                      "type": "string"
                    },
                    "maxItems": 1000,
                    "type": "array"
                  },
                  "adSetIds": {
                    "description": "Google ad group ids Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "maxItems": 1000,
                    "type": "array"
                  },
                  "campaignIds": {
                    "description": "Google campaign ids Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "pattern": "^\\d+$",
                      "type": "string"
                    },
                    "maxItems": 1000,
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "customerId": {
                    "description": "Alias of adAccountId",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "keywordIds": {
                    "description": "Google keyword criterion ids, {adGroupId}~{criterionId} Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "pattern": "^\\d+~\\d+$",
                      "type": "string"
                    },
                    "maxItems": 1000,
                    "type": "array"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "attached": {
                      "description": "Links created by this call",
                      "type": "integer"
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "labelId": {
                      "type": "string"
                    },
                    "unchanged": {
                      "description": "Targets that already carried the label",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Label attached"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Attach a Google Ads label",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.attach_ad_label@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "76468858c2eed14c6a2d2bce8db562b93c1fc42151c0e357bae2a21fe56cc3a8"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_labels_labelid_assignments",
          "method": "POST",
          "path": "/apis/v1/ads/labels/{labelId}/assignments"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_labels_labelid_assignments"
      }
    },
    "/apis/v1/ads/lead-forms": {
      "get": {
        "description": "Lead Gen. Read only. Lists the lead forms on a Facebook Page or LinkedIn Company Page. Meta: forms on the connected Facebook Page. Pass either the `metaads` ads connection (the Page is taken from the Facebook account linked to it) or the Facebook account itself. LinkedIn: forms owned by the ad account's Company Page. Pass `adAccountId` (LinkedIn forms are org-owned). Requires the Ads add-on.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_lead_forms",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "LinkedIn only: the LinkedIn ad account id (used to resolve the owning organization). Required for LinkedIn.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "forms": {
                      "items": {
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "pagination": {
                      "properties": {
                        "cursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "hasMore": {
                          "type": "boolean"
                        }
                      },
                      "type": "object"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Forms list."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List lead forms",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_lead_forms@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "06d9e654058469e69f07663a1288ffb51dc5bf2d1440002a03e3a8f7db8fae2f"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_lead_forms",
          "method": "GET",
          "path": "/apis/v1/ads/lead-forms"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_lead_forms"
      },
      "post": {
        "description": "Lead Gen. Changes the ad account without starting or raising spend; audited. Creates a lead form on a Facebook Page or LinkedIn Company Page to collect contact details from ads. The form content goes inside `platformSpecificData` for both platforms (the shape is selected by the connectionId's platform). Requires the Ads add-on. NOT idempotent: a retry creates a second form. ### Meta Created on the connected Facebook Page (POST /{page-id}/leadgen_forms).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_lead_forms",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch",
                "privacyPolicyUrl": "https://example.com/landing"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "followUpActionUrl": {
                    "description": "Deprecated: use platformSpecificData.followUpActionUrl.",
                    "format": "uri",
                    "type": "string"
                  },
                  "isOptimizedForQuality": {
                    "description": "Deprecated: use platformSpecificData.isOptimizedForQuality.",
                    "type": "boolean"
                  },
                  "locale": {
                    "description": "Deprecated: use platformSpecificData.locale.",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 200,
                    "type": "string"
                  },
                  "platformSpecificData": {
                    "description": "Form content; the shape is selected by the connectionId's platform. Unknown fields are a 400 (strict-parsed).",
                    "oneOf": [
                      {
                        "description": "MetaLeadFormPlatformData",
                        "properties": {
                          "blockDisplayForNonTargetedViewer": {
                            "type": "boolean"
                          },
                          "businessPhoneNumber": {
                            "description": "International E.164 number the CALL_BUSINESS thank-you button dials (Meta thank_you_page.business_phone_number). Must start with + and the country calling code matching countryCode.",
                            "type": "string"
                          },
                          "contextCard": {
                            "properties": {
                              "buttonText": {
                                "type": "string"
                              },
                              "content": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "coverPhoto": {
                                "description": "Direct public JPEG or PNG image URL, up to 5 MB. Uploaded as an unpublished Page photo and attached to the form. Redirects, Ad Image hashes and IDs are not supported.",
                                "format": "uri",
                                "type": "string"
                              },
                              "style": {
                                "enum": [
                                  "LIST_STYLE",
                                  "PARAGRAPH_STYLE"
                                ],
                                "type": "string"
                              },
                              "title": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "countryCode": {
                            "description": "ISO 3166-1 alpha-2 country of businessPhoneNumber (Meta thank_you_page.country_code), sent in uppercase. Required when thankYouButtonType is CALL_BUSINESS and a 400 with any other button type.",
                            "pattern": "^[A-Za-z]{2}$",
                            "type": "string"
                          },
                          "customDisclaimer": {
                            "description": "Consent section with checkboxes (Meta custom_disclaimer). Each lead's answers come back on the lead, and a lead_received workflow only messages leads that ticked its consentCheckboxKey.",
                            "properties": {
                              "body": {
                                "type": "string"
                              },
                              "checkboxes": {
                                "items": {
                                  "properties": {
                                    "isCheckedByDefault": {
                                      "default": false,
                                      "type": "boolean"
                                    },
                                    "isRequired": {
                                      "default": false,
                                      "type": "boolean"
                                    },
                                    "key": {
                                      "type": "string"
                                    },
                                    "text": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key",
                                    "text"
                                  ],
                                  "type": "object"
                                },
                                "minItems": 1,
                                "type": "array"
                              },
                              "title": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "body",
                              "checkboxes",
                              "title"
                            ],
                            "type": "object"
                          },
                          "followUpActionUrl": {
                            "format": "uri",
                            "type": "string"
                          },
                          "isOptimizedForQuality": {
                            "description": "Set true for a higher-intent form (adds a review step before submit).",
                            "type": "boolean"
                          },
                          "isPhoneSmsVerifyEnabled": {
                            "default": false,
                            "description": "Requires the lead to verify their phone number over SMS before the form submits (Meta is_phone_sms_verify_enabled). Only meaningful on a form with a PHONE question. Meta can restrict this parameter to apps holding a capability.",
                            "type": "boolean"
                          },
                          "locale": {
                            "type": "string"
                          },
                          "privacyPolicyLinkText": {
                            "maxLength": 70,
                            "type": "string"
                          },
                          "questionPageCustomHeadline": {
                            "type": "string"
                          },
                          "questions": {
                            "items": {
                              "properties": {
                                "inline_context": {
                                  "type": "string"
                                },
                                "key": {
                                  "description": "CUSTOM questions only.",
                                  "type": "string"
                                },
                                "label": {
                                  "description": "CUSTOM questions only.",
                                  "type": "string"
                                },
                                "options": {
                                  "items": {
                                    "properties": {
                                      "key": {
                                        "type": "string"
                                      },
                                      "value": {
                                        "type": "string"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "type": {
                                  "description": "EMAIL, PHONE, FULL_NAME, FIRST_NAME, LAST_NAME, CUSTOM, …",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "type"
                              ],
                              "type": "object"
                            },
                            "minItems": 1,
                            "type": "array"
                          },
                          "thankYouBody": {
                            "type": "string"
                          },
                          "thankYouButtonText": {
                            "type": "string"
                          },
                          "thankYouButtonType": {
                            "description": "Meta thank_you_page.button_type. Defaults to VIEW_WEBSITE. Case-insensitive, sent to Meta in uppercase. CALL_BUSINESS requires businessPhoneNumber and countryCode (a 400 otherwise).",
                            "type": "string"
                          },
                          "thankYouEnableMessenger": {
                            "default": false,
                            "description": "Sent as Meta thank_you_page.enable_messenger (boolean). Accepted only inside platformSpecificData: a top-level thankYouEnableMessenger is a 400.",
                            "type": "boolean"
                          },
                          "thankYouTitle": {
                            "type": "string"
                          },
                          "thankYouWebsiteUrl": {
                            "format": "uri",
                            "type": "string"
                          }
                        },
                        "required": [
                          "questions"
                        ],
                        "type": "object"
                      },
                      {
                        "description": "LinkedInLeadFormPlatformData",
                        "properties": {
                          "adAccountId": {
                            "description": "LinkedIn ad account id (resolves the owning organization).",
                            "type": "string"
                          },
                          "consents": {
                            "items": {
                              "properties": {
                                "description": {
                                  "type": "string"
                                },
                                "required": {
                                  "default": false,
                                  "description": "Whether the viewer must tick this consent to submit. Defaults to false.",
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "description"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "description": {
                            "maxLength": 1500,
                            "type": "string"
                          },
                          "headline": {
                            "maxLength": 255,
                            "type": "string"
                          },
                          "locale": {
                            "properties": {
                              "country": {
                                "type": "string"
                              },
                              "language": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "questions": {
                            "items": {
                              "oneOf": [
                                {
                                  "properties": {
                                    "kind": {
                                      "enum": [
                                        "text"
                                      ],
                                      "type": "string"
                                    },
                                    "maxResponseLength": {
                                      "description": "Defaults to 300 on LinkedIn's side.",
                                      "type": "integer"
                                    },
                                    "name": {
                                      "type": "string"
                                    },
                                    "question": {
                                      "type": "string"
                                    },
                                    "required": {
                                      "type": "boolean"
                                    },
                                    "responseEditable": {
                                      "type": "boolean"
                                    }
                                  },
                                  "required": [
                                    "kind",
                                    "name",
                                    "question"
                                  ],
                                  "type": "object"
                                },
                                {
                                  "properties": {
                                    "choices": {
                                      "items": {
                                        "properties": {
                                          "id": {
                                            "type": "integer"
                                          },
                                          "text": {
                                            "type": "string"
                                          }
                                        },
                                        "required": [
                                          "id",
                                          "text"
                                        ],
                                        "type": "object"
                                      },
                                      "minItems": 1,
                                      "type": "array"
                                    },
                                    "kind": {
                                      "enum": [
                                        "multipleChoice"
                                      ],
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    },
                                    "question": {
                                      "type": "string"
                                    },
                                    "required": {
                                      "type": "boolean"
                                    },
                                    "responseEditable": {
                                      "type": "boolean"
                                    }
                                  },
                                  "required": [
                                    "choices",
                                    "kind",
                                    "name",
                                    "question"
                                  ],
                                  "type": "object"
                                }
                              ]
                            },
                            "minItems": 1,
                            "type": "array"
                          },
                          "state": {
                            "description": "Defaults to DRAFT.",
                            "enum": [
                              "DRAFT",
                              "PUBLISHED"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "adAccountId",
                          "description",
                          "headline",
                          "questions"
                        ],
                        "type": "object"
                      }
                    ]
                  },
                  "privacyPolicyLinkText": {
                    "description": "Deprecated: use platformSpecificData.privacyPolicyLinkText.",
                    "maxLength": 70,
                    "type": "string"
                  },
                  "privacyPolicyUrl": {
                    "format": "uri",
                    "type": "string"
                  },
                  "questions": {
                    "description": "Deprecated (Meta legacy shape): use platformSpecificData.questions.",
                    "items": {
                      "properties": {
                        "inline_context": {
                          "type": "string"
                        },
                        "key": {
                          "description": "CUSTOM questions only.",
                          "type": "string"
                        },
                        "label": {
                          "description": "CUSTOM questions only.",
                          "type": "string"
                        },
                        "options": {
                          "items": {
                            "properties": {
                              "key": {
                                "type": "string"
                              },
                              "value": {
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "type": {
                          "description": "EMAIL, PHONE, FULL_NAME, FIRST_NAME, LAST_NAME, CUSTOM, …",
                          "type": "string"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "type": "object"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "thankYouBody": {
                    "description": "Deprecated: use platformSpecificData.thankYouBody.",
                    "type": "string"
                  },
                  "thankYouButtonText": {
                    "description": "Deprecated: use platformSpecificData.thankYouButtonText.",
                    "type": "string"
                  },
                  "thankYouButtonType": {
                    "description": "Deprecated: use platformSpecificData.thankYouButtonType.",
                    "type": "string"
                  },
                  "thankYouTitle": {
                    "description": "Deprecated: use platformSpecificData.thankYouTitle.",
                    "type": "string"
                  },
                  "thankYouWebsiteUrl": {
                    "description": "Deprecated: use platformSpecificData.thankYouWebsiteUrl.",
                    "format": "uri",
                    "type": "string"
                  }
                },
                "required": [
                  "name",
                  "privacyPolicyUrl"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "form": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Created form."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a lead form",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_lead_form@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "3f3fda64e2e74e14506c80ec5b74f2b2c2a945b3b27c430e69e39fd7205b9df4"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_lead_forms",
          "method": "POST",
          "path": "/apis/v1/ads/lead-forms"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_lead_forms"
      }
    },
    "/apis/v1/ads/lead-forms/{formId}": {
      "delete": {
        "description": "Lead Gen. Changes the ad account without starting or raising spend; audited. Archives a lead form so it can no longer be used (neither Meta nor LinkedIn allows deleting one). Neither platform hard-deletes a form; this archives it (Meta status=ARCHIVED; LinkedIn state=ARCHIVED via PARTIAL_UPDATE). Meta forms must belong to the Page the connectionId manages.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_lead_forms_formid",
        "parameters": [
          {
            "description": "Numeric form id (Meta leadgen_form id or LinkedIn leadForm id).",
            "in": "path",
            "name": "formId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "archived": {
                      "type": "boolean"
                    },
                    "formId": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Archived."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Archive a lead form",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.archive_lead_form@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "c72a4e445355a7f531a798aaf556126297c5dc3be9933971d94839a4f30c1f76"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_lead_forms_formid",
          "method": "DELETE",
          "path": "/apis/v1/ads/lead-forms/{formId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_lead_forms_formid"
      },
      "get": {
        "description": "Lead Gen. Read only. Shows a lead form in full, including its questions and thank-you page. Returns the full form, including the thank-you page, so a form can be diffed against what was created. Meta forms are scoped to the Page the connectionId manages: a form on any other Page is a 404, never a read.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_lead_forms_formid",
        "parameters": [
          {
            "description": "Numeric form id (Meta leadgen_form id or LinkedIn leadForm id).",
            "in": "path",
            "name": "formId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta only. A Graph field selection passed through verbatim to GET /{form-id}, replacing the default projection, so fields Meta adds later are reachable without an API change. Field names, commas and {} expansion only.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "maxLength": 2000,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "form": {
                      "oneOf": [
                        {
                          "description": "A Meta Lead Gen form as Graph returns it, in Meta's own snake_case. Read through GET /apis/v1/ads/lead-forms/{formId}.",
                          "properties": {
                            "allow_organic_lead": {
                              "description": "Whether the form can also be submitted from an organic Page post.",
                              "type": "boolean"
                            },
                            "block_display_for_non_targeted_viewer": {
                              "type": "boolean"
                            },
                            "context_card": {
                              "properties": {
                                "button_text": {
                                  "type": "string"
                                },
                                "content": {
                                  "items": {
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "cover_photo": {
                                  "properties": {
                                    "id": {
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                },
                                "id": {
                                  "type": "string"
                                },
                                "style": {
                                  "enum": [
                                    "LIST_STYLE",
                                    "PARAGRAPH_STYLE"
                                  ],
                                  "type": "string"
                                },
                                "title": {
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "created_time": {
                              "format": "date-time",
                              "type": "string"
                            },
                            "expired_leads_count": {
                              "description": "Leads Meta has aged out of the retention window.",
                              "type": "integer"
                            },
                            "follow_up_action_text": {
                              "type": "string"
                            },
                            "follow_up_action_url": {
                              "format": "uri",
                              "type": "string"
                            },
                            "id": {
                              "type": "string"
                            },
                            "is_optimized_for_quality": {
                              "type": "boolean"
                            },
                            "leads_count": {
                              "type": "integer"
                            },
                            "legal_content": {
                              "description": "Privacy policy and custom disclaimer as Meta stores them.",
                              "properties": {
                                "custom_disclaimer": {
                                  "description": "Set in Meta form builder only; there is no create parameter for it.",
                                  "type": "object"
                                },
                                "id": {
                                  "type": "string"
                                },
                                "privacy_policy": {
                                  "properties": {
                                    "link_text": {
                                      "type": "string"
                                    },
                                    "url": {
                                      "format": "uri",
                                      "type": "string"
                                    }
                                  },
                                  "type": "object"
                                }
                              },
                              "type": "object"
                            },
                            "locale": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "organic_leads_count": {
                              "type": "integer"
                            },
                            "page_id": {
                              "description": "Owning Facebook Page. A form on any other Page is a 404, whether read or archived.",
                              "type": "string"
                            },
                            "privacy_policy_url": {
                              "format": "uri",
                              "type": "string"
                            },
                            "question_page_custom_headline": {
                              "type": "string"
                            },
                            "questions": {
                              "items": {
                                "properties": {
                                  "conditional_questions_choices": {
                                    "description": "READ-ONLY. Which answers reveal the conditional group.",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "conditional_questions_group_id": {
                                    "description": "READ-ONLY. Conditional logic can only be authored in Meta form builder; Meta has no create parameter for it.",
                                    "type": "string"
                                  },
                                  "dependent_conditional_questions": {
                                    "description": "READ-ONLY. Questions revealed by the conditional group.",
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "id": {
                                    "type": "string"
                                  },
                                  "inline_context": {
                                    "type": "string"
                                  },
                                  "key": {
                                    "type": "string"
                                  },
                                  "label": {
                                    "type": "string"
                                  },
                                  "options": {
                                    "items": {
                                      "additionalProperties": true,
                                      "type": "object"
                                    },
                                    "type": "array"
                                  },
                                  "type": {
                                    "description": "EMAIL, PHONE, FULL_NAME, CUSTOM, ...",
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "type": "array"
                            },
                            "status": {
                              "description": "One of ACTIVE, ARCHIVED, DELETED or DRAFT.",
                              "type": "string"
                            },
                            "thank_you_page": {
                              "description": "The form's single ending page, mirroring the thankYou* create fields. Meta has exactly one per form; there is no multiple-ending-page API (thank_you_pages and ending_pages are not Graph fields).",
                              "properties": {
                                "body": {
                                  "type": "string"
                                },
                                "business_phone_number": {
                                  "type": "string"
                                },
                                "button_text": {
                                  "type": "string"
                                },
                                "button_type": {
                                  "type": "string"
                                },
                                "country_code": {
                                  "type": "string"
                                },
                                "enable_messenger": {
                                  "type": "boolean"
                                },
                                "id": {
                                  "type": "string"
                                },
                                "lead_gen_use_case": {
                                  "type": "string"
                                },
                                "status": {
                                  "type": "string"
                                },
                                "title": {
                                  "type": "string"
                                },
                                "website_url": {
                                  "format": "uri",
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "tracking_parameters": {
                              "description": "Custom key/value pairs attached to every lead of this form.",
                              "items": {
                                "properties": {
                                  "key": {
                                    "type": "string"
                                  },
                                  "value": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              },
                              "type": "array"
                            }
                          },
                          "type": "object"
                        },
                        {
                          "type": "object"
                        }
                      ]
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Form metadata. Meta forms follow MetaLeadForm; LinkedIn forms return LinkedIn's own adForm shape."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get a lead form",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_lead_form@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "94360e09326cbd87d25ab6736039ca78407d4295a4e54ca5bce695d0085be770"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_lead_forms_formid",
          "method": "GET",
          "path": "/apis/v1/ads/lead-forms/{formId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_lead_forms_formid"
      }
    },
    "/apis/v1/ads/lead-forms/{formId}/leads": {
      "get": {
        "description": "Lead Gen. Read only. Lists the leads submitted through one Meta lead form. ### Accounts Accepts either of these with leads_retrieval access to the form: a Facebook account a metaads business-login account, which uses its system-user token without a posting parent ### Freshness `meta.lastCheckedAt` says when that pass last ran, so polling this endpoint faster than that returns nothing new.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_lead_forms_formid_leads",
        "parameters": [
          {
            "in": "path",
            "name": "formId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Unix seconds.",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "leads": {
                      "items": {
                        "properties": {
                          "adId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "consents": {
                            "description": "Meta lead forms only: the answer to every custom disclaimer checkbox, required or optional. Empty when the form has none, and may be empty on leads stored before 2026-10-22. LinkedIn leads do not carry the field.",
                            "items": {
                              "additionalProperties": true,
                              "description": "One custom disclaimer checkbox on a Meta lead form (for example a TCPA call or SMS consent), as Meta returns it in custom_disclaimer_responses.",
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "createdTime": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "fieldData": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "fields": {
                            "additionalProperties": {
                              "type": "string"
                            },
                            "type": "object"
                          },
                          "formId": {
                            "type": "string"
                          },
                          "id": {
                            "description": "Meta leadgenId.",
                            "type": "string"
                          },
                          "leadId": {
                            "description": "Only on persisted leads.",
                            "type": "string"
                          },
                          "status": {
                            "description": "Lead status (see PATCH /apis/v1/ads/leads/{id}). Only on persisted leads.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "connectionId": {
                          "description": "The ads connection (adc_...) the object belongs to.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "formId": {
                          "type": "string"
                        },
                        "lastCheckedAt": {
                          "description": "For persisted leads, the last reconcile pass for the Page (null before the first one). For live reads, when the cached Graph read was made.",
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "lastUpdated": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "platform": {
                          "type": "string"
                        },
                        "source": {
                          "description": "live: read from Meta because none are stored for this form yet.",
                          "enum": [
                            "persisted",
                            "live"
                          ],
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "pagination": {
                      "properties": {
                        "cursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "hasMore": {
                          "type": "boolean"
                        }
                      },
                      "type": "object"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Leads for the form."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List leads for a single form",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_form_leads@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "974e7f7df5c196e75e8e94ea83c21a8022dd3fb5ef9215c4454186a0142fe35e"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_lead_forms_formid_leads",
          "method": "GET",
          "path": "/apis/v1/ads/lead-forms/{formId}/leads"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_lead_forms_formid_leads"
      }
    },
    "/apis/v1/ads/lead-forms/{formId}/test-leads": {
      "delete": {
        "description": "Lead Gen. Changes the ad account without starting or raising spend; audited. Deletes the test lead on a Meta lead form so you can submit a new one (Meta allows only one at a time). Removes a test lead created for the form (DELETE /{leadgen_id}). Meta keeps one test lead per form and refuses a second until the first is gone. The same test lead appears in Meta's Lead Ads Testing Tool. Meta only deletes test leads; a real lead is refused.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_lead_forms_formid_test_leads",
        "parameters": [
          {
            "in": "path",
            "name": "formId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "The test lead id returned by createTestLead (or shown in the Testing Tool). Omitted = the test lead currently on the form.",
            "in": "query",
            "name": "leadId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "deleted": {
                      "description": "Ids of the test leads removed.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Test lead deleted."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete a test lead",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_test_lead@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "3cf4f4a687fa5a9faef855d4ed401e55bc0a265b6fe68b8b56508d70aa7eb1bc"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_lead_forms_formid_test_leads",
          "method": "DELETE",
          "path": "/apis/v1/ads/lead-forms/{formId}/test-leads"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_lead_forms_formid_test_leads"
      },
      "post": {
        "description": "Lead Gen. Changes the ad account without starting or raising spend; audited. Submits a test lead to a Meta lead form so you can check your lead retrieval without running ads. Submits a test lead against the form (POST /{form-id}/test_leads) to exercise retrieval without waiting for real ad impressions. Meta allows one test lead per form at a time.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_lead_forms_formid_test_leads",
        "parameters": [
          {
            "in": "path",
            "name": "formId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "fieldData": [
                  {
                    "name": "Winter launch",
                    "values": [
                      "example"
                    ]
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "fieldData": {
                    "items": {
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "values": {
                          "items": {
                            "type": "string"
                          },
                          "minItems": 1,
                          "type": "array"
                        }
                      },
                      "required": [
                        "name",
                        "values"
                      ],
                      "type": "object"
                    },
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "fieldData"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "testLead": {
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Test lead created."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a test lead",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_test_lead@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0a7cb97a584a6e4b3d21d2bbaee8014dfb7f2a8d37d9b3e122cdd14cc031242a"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_lead_forms_formid_test_leads",
          "method": "POST",
          "path": "/apis/v1/ads/lead-forms/{formId}/test-leads"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_lead_forms_formid_test_leads"
      }
    },
    "/apis/v1/ads/leads": {
      "get": {
        "description": "Lead Gen. Read only. Lists the leads submitted through your Meta or LinkedIn lead forms, newest first. Requires the Ads add-on. ### Meta (default) ### LinkedIn When `connectionId` is a LinkedIn ads account, `adAccountId` is required. Reading LinkedIn responses needs the `r_marketing_leadgen_automation` permission. Accounts connected before it was added must reconnect.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_leads",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Filter to a single lead form.",
            "in": "query",
            "name": "formId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only. Comma-separated lead statuses: new, contacted, unreachable, qualified, converted, disqualified.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only. The platform campaign id the lead came from. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "meta skips the LinkedIn live fetch; linkedin requires connectionId to be a LinkedIn ads connection (400 otherwise).",
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "meta",
                "linkedin"
              ],
              "type": "string"
            }
          },
          {
            "description": "Meta only. Case-insensitive text search over the lead's answers and the form name.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "maxLength": 200,
              "type": "string"
            }
          },
          {
            "description": "LinkedIn only: the LinkedIn ad account id whose responses to read (owner-scoped finder).",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Unix seconds; only leads created at/after this timestamp. Millisecond timestamps return 400 with instructions to divide by 1000.",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "maximum": 253402300799,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Keyset cursor from a previous response's pagination.cursor (Meta: AdLead id; LinkedIn: numeric start offset).",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "leads": {
                      "items": {
                        "properties": {
                          "adId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "adsetId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "consents": {
                            "description": "Meta lead forms only: the answer to every custom disclaimer checkbox, required or optional. Empty when the form has none, and may be empty on leads stored before 2026-10-22. LinkedIn leads do not carry the field.",
                            "items": {
                              "additionalProperties": true,
                              "description": "One custom disclaimer checkbox on a Meta lead form (for example a TCPA call or SMS consent), as Meta returns it in custom_disclaimer_responses.",
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "contactId": {
                            "description": "The contact a lead_received workflow created or matched for this lead.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "conversationId": {
                            "description": "The Inbox conversation a lead_received workflow opened with the lead.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdTime": {
                            "description": "ISO 8601.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "currency": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "fieldData": {
                            "description": "Raw Meta field_data.",
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "fields": {
                            "additionalProperties": {
                              "type": "string"
                            },
                            "description": "Question key → answer. On LinkedIn, the key is the lowercased predefinedField, else the question name, else the numeric questionId; multiple-choice values are option labels (unlike Meta, which returns the option key).",
                            "type": "object"
                          },
                          "firstContactedAt": {
                            "description": "When the first WhatsApp message to the lead was delivered.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "formId": {
                            "type": "string"
                          },
                          "formName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "type": "string"
                          },
                          "isOrganic": {
                            "type": "boolean"
                          },
                          "leadgenId": {
                            "description": "Meta lead id. On LinkedIn, the leadFormResponse id.",
                            "type": "string"
                          },
                          "status": {
                            "description": "Meta leads only. `contacted` is set when the first WhatsApp message of a lead_received workflow is delivered, `unreachable` when it fails or the phone number is not valid.",
                            "enum": [
                              "new",
                              "contacted",
                              "unreachable",
                              "qualified",
                              "converted",
                              "disqualified"
                            ],
                            "type": "string"
                          },
                          "statusChangedAt": {
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "value": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "webhookDeliveredAt": {
                            "description": "Meta leads only.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "lastCheckedAt": {
                          "description": "Null when no leads matched or before the first pass.",
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "lastUpdated": {
                          "format": "date-time",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "pagination": {
                      "properties": {
                        "cursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "hasMore": {
                          "type": "boolean"
                        }
                      },
                      "type": "object"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Lead list."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List submitted leads",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_leads@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "42b06b9f403acce6f9d371a53ee1ae33eda3c99a97599625c9e28b78c0a2f541"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_leads",
          "method": "GET",
          "path": "/apis/v1/ads/leads"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_leads"
      }
    },
    "/apis/v1/ads/leads/counts": {
      "get": {
        "description": "Lead Gen. Read only. Every status is present, with 0 when no lead has it. Requires the Ads add-on.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_leads_counts",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "The platform campaign id the leads came from. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "counts": {
                      "properties": {
                        "contacted": {
                          "type": "integer"
                        },
                        "converted": {
                          "type": "integer"
                        },
                        "disqualified": {
                          "type": "integer"
                        },
                        "new": {
                          "type": "integer"
                        },
                        "qualified": {
                          "type": "integer"
                        },
                        "unreachable": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "status": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Lead counts."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Count leads by status",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.count_leads@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "7a007c63bef8a962f01db5dc30fa5eb44b4bd708c2657c252bba1da06e40d263"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_leads_counts",
          "method": "GET",
          "path": "/apis/v1/ads/leads/counts"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_leads_counts"
      }
    },
    "/apis/v1/ads/library": {
      "get": {
        "description": "Ad Library. Read only. Searches Meta's or LinkedIn's public Ad Library to see what ads other advertisers run, for competitor and market research. ### Which library is searched LinkedIn's Ad Library (`GET /rest/adLibrary`) runs on a connected `linkedin` / `linkedinads` account, passed as `connectionId`. Passing a Meta account as `connectionId` also selects Meta. Rows are returned in the platform's raw shape under `data`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_library",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Which archive to search. `meta` needs no connectionId. Required unless connectionId is given.",
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "meta",
                "linkedin"
              ],
              "type": "string"
            }
          },
          {
            "description": "Keyword search. Meta does not translate it, so write it in the ads' language. Required unless pageIds (Meta) or advertiser (LinkedIn) is given.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "description": "Meta only. Comma-separated Facebook Page ids (max 10) whose ads to list.",
            "in": "query",
            "name": "pageIds",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "LinkedIn only. Advertiser (Page) name to search.",
            "in": "query",
            "name": "advertiser",
            "required": false,
            "schema": {
              "maxLength": 100,
              "type": "string"
            }
          },
          {
            "description": "Comma-separated ISO 3166-1 alpha-2 codes the ads reached. Meta defaults to ALL (an explicit ALL is Meta-only); LinkedIn searches every market when omitted.",
            "in": "query",
            "name": "countries",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only.",
            "in": "query",
            "name": "adType",
            "required": false,
            "schema": {
              "default": "ALL",
              "enum": [
                "ALL",
                "POLITICAL_AND_ISSUE_ADS",
                "HOUSING_ADS",
                "EMPLOYMENT_ADS",
                "FINANCIAL_PRODUCTS_AND_SERVICES_ADS"
              ],
              "type": "string"
            }
          },
          {
            "description": "Meta only. ACTIVE = eligible for delivery right now.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "default": "ACTIVE",
              "enum": [
                "ACTIVE",
                "INACTIVE",
                "ALL"
              ],
              "type": "string"
            }
          },
          {
            "description": "Meta only. Comma-separated publisher platforms: FACEBOOK, INSTAGRAM, AUDIENCE_NETWORK, MESSENGER, WHATSAPP, OCULUS, THREADS, STREAMING_SERVICES.",
            "in": "query",
            "name": "platforms",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only.",
            "in": "query",
            "name": "mediaType",
            "required": false,
            "schema": {
              "enum": [
                "ALL",
                "IMAGE",
                "MEME",
                "VIDEO",
                "NONE"
              ],
              "type": "string"
            }
          },
          {
            "description": "Meta only. Comma-separated ISO 639-1 codes of the ad text.",
            "in": "query",
            "name": "languages",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only. Earliest delivery date (YYYY-MM-DD). LinkedIn's archive does not filter by date, so it is a 400 there: filter on details.adStatistics.firstImpressionAt / latestImpressionAt instead (EU-delivered ads only).",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Meta only. Latest delivery date (YYYY-MM-DD); a 400 on LinkedIn, see since.",
            "in": "query",
            "name": "until",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Meta only. Whether q matches words in any order or as an exact phrase (comma-separate phrases to match all of them).",
            "in": "query",
            "name": "searchType",
            "required": false,
            "schema": {
              "default": "KEYWORD_UNORDERED",
              "enum": [
                "KEYWORD_UNORDERED",
                "KEYWORD_EXACT_PHRASE"
              ],
              "type": "string"
            }
          },
          {
            "description": "Meta only. Comma-separated Graph field override.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Rows per page. LinkedIn accepts at most 25.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "description": "One ad library entry, in the platform's shape. Meta: an ArchivedAd with: id, page_id, page_name, ad_creation_time, ad_delivery_start_time, ad_delivery_stop_time.",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "total": {
                          "description": "LinkedIn only. Total matching ads.",
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "platform": {
                      "enum": [
                        "meta",
                        "linkedin"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "data",
                    "paging",
                    "platform"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Archived ads (raw platform shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Search the public Ad Library",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.search_ad_library@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "b57356168ca21118ffea3520ed5214e8195d923340484c43a46636b1f802b768"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_library",
          "method": "GET",
          "path": "/apis/v1/ads/library"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_library"
      }
    },
    "/apis/v1/ads/local-services/leads": {
      "get": {
        "description": "Ad Insights. Read only. Lists the calls, messages and bookings your Google Local Services Ads generated, newest first. Leads (phone calls, messages, bookings) are read live from Google's `local_services_lead` resource. No persistence: Google is the source of truth, and lead/credit statuses keep changing server-side. Google never returns healthcare-category leads.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_local_services_leads",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Defaults to the account's connected customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Leads created at/after this day.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Leads created at/before this day.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "leadType",
            "required": false,
            "schema": {
              "enum": [
                "PHONE_CALL",
                "MESSAGE",
                "BOOKING"
              ],
              "type": "string"
            }
          },
          {
            "description": "Google LocalServicesLeadStatus enum value (e.g. NEW, BOOKED, WIPED_OUT).",
            "in": "query",
            "name": "leadStatus",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "true = only leads Google charged for.",
            "in": "query",
            "name": "chargedOnly",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Cursor from paging.nextPageToken of the previous page.",
            "in": "query",
            "name": "pageToken",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "properties": {
                          "categoryId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "charged": {
                            "type": "boolean"
                          },
                          "contact": {
                            "description": "Null for WIPED_OUT leads (contact erased by Google).",
                            "properties": {
                              "consumerName": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "email": {
                                "description": "Always null: Google Ads API v25 stopped returning the consumer email on Local Services leads.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "phoneNumber": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "createdTime": {
                            "description": "Google datetime in the customer's timezone (YYYY-MM-DD HH:MM:SS).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "creditState": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "creditStateLastUpdate": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "description": "Lead id; pass to /apis/v1/ads/local-services/leads/{leadId}/conversations.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "leadType": {
                            "description": "PHONE_CALL / MESSAGE / BOOKING.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "locale": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "serviceId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "nextPageToken": {
                          "description": "Null when the last page was returned.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Local Services leads"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Google Local Services Ads leads",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_local_services_leads@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1006f656e8ff3eac6990681f3b119e872cab3ddaf78278a06f2c8581518c46be"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_local_services_leads",
          "method": "GET",
          "path": "/apis/v1/ads/local-services/leads"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_local_services_leads"
      }
    },
    "/apis/v1/ads/local-services/leads/{leadId}/conversations": {
      "get": {
        "description": "Ad Insights. Read only. Shows the calls (with recordings) and messages exchanged with one Google Local Services lead, oldest first. Conversation entries of one Local Services lead: phone calls (duration, recording URL) and messages (text, attachment URLs), oldest first. Read live from `local_services_lead_conversation`, always scoped to a single lead. Call-recording URLs require read access on the Google Ads account.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_local_services_leads_lea_868b73",
        "parameters": [
          {
            "description": "Numeric lead id from /apis/v1/ads/local-services/leads.",
            "in": "path",
            "name": "leadId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Defaults to the account's connected customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Cursor from paging.nextPageToken of the previous page.",
            "in": "query",
            "name": "pageToken",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customerId": {
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "properties": {
                          "channel": {
                            "description": "PHONE_CALL / MESSAGE / SMS / EMAIL / WHATSAPP / ADS_API.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "eventDateTime": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "message": {
                            "description": "Only on message-channel entries.",
                            "properties": {
                              "attachmentUrls": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "text": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "participantType": {
                            "description": "ADVERTISER or CONSUMER.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "phoneCall": {
                            "description": "Only on PHONE_CALL entries.",
                            "properties": {
                              "callDurationMillis": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              },
                              "callRecordingUrl": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "nextPageToken": {
                          "description": "Null when the last page was returned.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Lead conversations"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List lead conversations",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_local_services_lead_conversations@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "327b20f3d0b276e5e318e359a6aa5fa2456cc3009239de24c8b083dd8734de57"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_local_services_leads_lea_868b73",
          "method": "GET",
          "path": "/apis/v1/ads/local-services/leads/{leadId}/conversations"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_local_services_leads_lea_868b73"
      }
    },
    "/apis/v1/ads/messaging": {
      "post": {
        "description": "Messaging Ads. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates a messaging ad that spends the given budget. validateOnly=true checks the request without acting and needs no confirmation. Creates a Meta ad that opens a chat with you on WhatsApp, Messenger or Instagram Direct when someone taps it. ### Destinations `destination` selects where the tapped ad opens a conversation: WhatsApp the Page's Messenger inbox the linked Instagram account's Direct inbox `destinations` puts two or three of them on one ad set and lets Meta pick the app per viewer.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_messaging",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_757082720485182",
                "budgetAmount": 2.61,
                "budgetType": "daily",
                "connectionId": "adc_7f3k2m9q",
                "creatives": [
                  {
                    "objectStoryId": "811889972008357_123456789"
                  }
                ],
                "destination": "whatsapp",
                "name": "WhatsApp existing post",
                "status": "PAUSED"
              },
              "schema": {
                "additionalProperties": true,
                "description": "Besides the `required` list, the request must use EXACTLY ONE of these shapes: Single-creative: `headline`, `body`, and one of `imageUrl` / `video`, OR `platformPostId` / `objectStoryId` to reuse an organic post.",
                "properties": {
                  "adAccountId": {
                    "description": "Meta ad account ID, e.g. `act_123456789`.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "adSetId": {
                    "description": "Attaches the creatives to this EXISTING messaging ad set instead of building a campaign, so the ad set keeps its learning phase. Its `destination_type` must match the ad's destination. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "adSetName": {
                    "description": "Exact name for the ad set this request provisions. Omitted keeps ` - Ad Set`. Ignored with `adSetId`.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "adSetStatus": {
                    "description": "Ad-set-level status, same semantics as `POST /apis/v1/ads/create`. Sets the new ad set's switch alone and overrides `status` for it.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "adStatus": {
                    "description": "Request-side publish switch for `adStatus` on ad creation endpoints only (`status`, `campaignStatus` and `adSetStatus` carry their own inline ACTIVE/PAUSED enum there; the status-update endpoints are a separate lowercase `active`/`paused`…",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "advantageAudience": {
                    "description": "Meta's Advantage+ audience expansion. `0` (default) keeps targeting strict; `1` lets Meta expand beyond the supplied targeting when its delivery system finds better matches. Always sent on CREATE (Meta requires it).",
                    "enum": [
                      0,
                      1
                    ],
                    "type": "integer"
                  },
                  "ageMax": {
                    "maximum": 65,
                    "minimum": 13,
                    "type": "integer"
                  },
                  "ageMin": {
                    "maximum": 65,
                    "minimum": 13,
                    "type": "integer"
                  },
                  "audienceExclude": {
                    "description": "Custom or lookalike audience ids to exclude. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "audienceId": {
                    "description": "Custom audience ID to target. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "audienceInclude": {
                    "description": "Custom or lookalike audience ids to include. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "behaviors": {
                    "description": "Behavior ids from /apis/v1/ads/targeting/search?dimension=behavior. Meta: each dimension is its own flexible_spec entry (OR within, AND across). TikTok: video/creator interaction categories, sent as the ad group's actions.",
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "bidAmount": {
                    "description": "Whole currency units (e.g. `5` = $5.00 on a USD account). Required when `bidStrategy` is `LOWEST_COST_WITH_BID_CAP` or `COST_CAP`; rejected otherwise.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "bidStrategy": {
                    "description": "Meta bid strategy applied to the shared ad set. Defaults to `LOWEST_COST_WITHOUT_CAP` (auto-bid) when omitted. `LOWEST_COST_WITH_BID_CAP` and `COST_CAP` require `bidAmount`. `LOWEST_COST_WITH_MIN_ROAS` requires `roasAverageFloor`.",
                    "enum": [
                      "LOWEST_COST_WITHOUT_CAP",
                      "LOWEST_COST_WITH_BID_CAP",
                      "COST_CAP",
                      "LOWEST_COST_WITH_MIN_ROAS"
                    ],
                    "type": "string"
                  },
                  "body": {
                    "description": "Primary text shown above the image / video. Single-creative shape only. Mutually exclusive with `creatives[]`.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "budgetAmount": {
                    "description": "Budget amount in the ad account's currency major units (e.g. dollars for USD, not cents). Must be > 0. Required unless `adSetId` is set (the ad set owns it) or `existingCampaignId` names a campaign with a campaign budget.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "budgetLevel": {
                    "description": "Where the budget lives. `adset` (default) puts it on the new ad set. `campaign` creates an Advantage campaign budget (CBO): the budget and bid strategy sit on the campaign and the ad set inherits them, same as POST /apis/v1/ads/create.",
                    "enum": [
                      "adset",
                      "campaign"
                    ],
                    "type": "string"
                  },
                  "budgetType": {
                    "description": "Required unless `adSetId` is set or `existingCampaignId` names a campaign with a campaign budget. `lifetime` requires `endDate`.",
                    "enum": [
                      "daily",
                      "lifetime"
                    ],
                    "type": "string"
                  },
                  "campaignName": {
                    "description": "Exact name for the campaign this request provisions. Omitted keeps ` - Campaign`. Ignored with `adSetId` (the ad set already has a campaign).",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "campaignStatus": {
                    "description": "Campaign-level status, same semantics as `POST /apis/v1/ads/create`. Defaults to `status`. `PAUSED`: holds the new campaign off while the ad set and ads switch on (one resume call brings the whole hierarchy live).",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "carouselCards": {
                    "description": "Messaging and CTWA only (a 400 on POST /apis/v1/ads/call). A hand-built carousel of 2-10 image cards, sent to Meta in the given order as `link_data.child_attachments`.",
                    "items": {
                      "description": "One card of a messaging ad carousel (Meta link_data.child_attachments). Every card opens the same conversation, so a card has no link of its own.",
                      "properties": {
                        "callToAction": {
                          "description": "Optional. Must equal the destination's messaging call to action (WHATSAPP_MESSAGE for whatsapp, MESSAGE_PAGE for messenger, INSTAGRAM_MESSAGE for instagram_direct; with `destinations` the first one listed).",
                          "type": "string"
                        },
                        "description": {
                          "description": "Card description, under the title.",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "headline": {
                          "description": "Card title (Meta name).",
                          "maxLength": 255,
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Card image. Uploaded to the ad account and sent as the card image_hash (by URL on validateOnly).",
                          "format": "uri",
                          "type": "string"
                        },
                        "linkUrl": {
                          "description": "Not accepted: a 400. The card tap opens the conversation, not a website.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "imageUrl"
                      ],
                      "type": "object"
                    },
                    "maxItems": 10,
                    "minItems": 2,
                    "type": "array"
                  },
                  "cities": {
                    "description": "City-level geo targeting for local CTWA campaigns. Each entry maps to Meta's TargetingGeoLocationCity; `key` is Meta's city ID. `radius` and `distance_unit` are coupled: set both or neither.",
                    "items": {
                      "properties": {
                        "distance_unit": {
                          "enum": [
                            "mile",
                            "kilometer"
                          ],
                          "type": "string"
                        },
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "radius": {
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "countries": {
                    "description": "ISO 3166-1 alpha-2 country codes. Defaults to `[\"US\"]` only when no other geo (`cities`, `regions`, `zips`, `metros`, `customLocations`) is supplied.",
                    "items": {
                      "maxLength": 2,
                      "minLength": 2,
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "countryGroups": {
                    "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                    "items": {
                      "enum": [
                        "africa",
                        "asia",
                        "europe",
                        "north_america",
                        "south_america",
                        "oceania",
                        "central_america",
                        "caribbean",
                        "eea",
                        "euro_area",
                        "nafta",
                        "mercosur",
                        "afta",
                        "apec",
                        "gcc",
                        "cisfta",
                        "emerging_markets",
                        "itunes_app_store",
                        "android_free_store",
                        "android_paid_store"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "creativeFeatures": {
                    "additionalProperties": {
                      "enum": [
                        "OPT_IN",
                        "OPT_OUT"
                      ],
                      "type": "string"
                    },
                    "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                    "type": "object"
                  },
                  "creatives": {
                    "description": "Multi-creative shape: N CTWA ads under one campaign + one ad set, sharing budget and targeting. Fresh and existing creatives can be mixed. Each entry supplies headline, body, and image/video, or a platformPostId or objectStoryId reference.",
                    "items": {
                      "description": "Supply headline, body, and image/video; or body and carouselCards (no headline); or exactly one existing post reference. References cannot be combined with headline, body, imageUrl, video or carouselCards; welcomeMessage works on all three.",
                      "properties": {
                        "body": {
                          "description": "Primary text shown above the image / video.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "carouselCards": {
                          "description": "A 2-10 card carousel for this entry instead of `imageUrl` / `video`; `body` is required. Same rules as the top-level `carouselCards`. Carousel and single-media entries can be mixed on one ad set.",
                          "items": {
                            "description": "One card of a messaging ad carousel (Meta link_data.child_attachments). Every card opens the same conversation, so a card has no link of its own.",
                            "properties": {
                              "callToAction": {
                                "description": "Optional. Must equal the destination's messaging call to action (WHATSAPP_MESSAGE for whatsapp, MESSAGE_PAGE for messenger, INSTAGRAM_MESSAGE for instagram_direct; with `destinations` the first one listed).",
                                "type": "string"
                              },
                              "description": {
                                "description": "Card description, under the title.",
                                "maxLength": 255,
                                "type": "string"
                              },
                              "headline": {
                                "description": "Card title (Meta name).",
                                "maxLength": 255,
                                "type": "string"
                              },
                              "imageUrl": {
                                "description": "Card image. Uploaded to the ad account and sent as the card image_hash (by URL on validateOnly).",
                                "format": "uri",
                                "type": "string"
                              },
                              "linkUrl": {
                                "description": "Not accepted: a 400. The card tap opens the conversation, not a website.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "imageUrl"
                            ],
                            "type": "object"
                          },
                          "maxItems": 10,
                          "minItems": 2,
                          "type": "array"
                        },
                        "creativeFeatures": {
                          "additionalProperties": {
                            "enum": [
                              "OPT_IN",
                              "OPT_OUT"
                            ],
                            "type": "string"
                          },
                          "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                          "type": "object"
                        },
                        "existingPostId": {
                          "description": "Alias of platformPostId, kept for existing callers. Sending both with different values is a 400.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "headline": {
                          "maxLength": 255,
                          "minLength": 1,
                          "type": "string"
                        },
                        "imageUrl": {
                          "description": "Image asset. Mutually exclusive with this entry's `video`. Required if neither `video` nor an existing post reference is supplied.",
                          "format": "uri",
                          "type": "string"
                        },
                        "objectStoryId": {
                          "description": "Messaging and CTWA only. Raw Facebook pageId_postId reference, used as object_story_id even with an Instagram account. Mutually exclusive with platformPostId and fresh creative fields.",
                          "pattern": "^\\d+_\\d+$",
                          "type": "string"
                        },
                        "platformPostId": {
                          "description": "Messaging and CTWA only. Platform post or reel ID, the same input boostPost takes as platformPostId. Mutually exclusive with objectStoryId and fresh creative fields. Facebook IDs become object_story_id.",
                          "minLength": 1,
                          "type": "string"
                        },
                        "video": {
                          "description": "Video creative. Mutually exclusive with this entry's `imageUrl`. Required if neither `imageUrl` nor an existing post reference is supplied.",
                          "properties": {
                            "id": {
                              "description": "Reuse a video already uploaded to this ad account (list them with GET /apis/v1/ads/videos) instead of re-uploading. Wins over `url`. Provide either `url` or `id`.",
                              "type": "string"
                            },
                            "thumbnailUrl": {
                              "description": "OPTIONAL: when omitted, the poster is auto-generated from Meta's own preferred video thumbnail. When Meta produces no candidate the request fails with a 502 platform_error (reason: video_thumbnail_unavailable).",
                              "format": "uri",
                              "type": "string"
                            },
                            "url": {
                              "description": "Public URL of the video to upload. Provide either `url` or `id`.",
                              "format": "uri",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "welcomeMessage": {
                          "description": "Custom chat welcome message for this entry: `text` plus exactly one of `prefillText` or `quickReplies` (400 otherwise). Same shape as the top-level `welcomeMessage` of the single-creative shape.",
                          "properties": {
                            "prefillText": {
                              "description": "Message put into the user's text input, ready to send. Replaces Meta's default. Exactly one of prefillText or quickReplies.",
                              "minLength": 1,
                              "type": "string"
                            },
                            "quickReplies": {
                              "description": "Tappable chips under the greeting instead of a prefilled message. Exactly one of prefillText or quickReplies.",
                              "items": {
                                "properties": {
                                  "payload": {
                                    "maxLength": 1000,
                                    "minLength": 1,
                                    "type": "string"
                                  },
                                  "title": {
                                    "description": "Chip label the person taps.",
                                    "maxLength": 20,
                                    "minLength": 1,
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "payload",
                                  "title"
                                ],
                                "type": "object"
                              },
                              "maxItems": 13,
                              "minItems": 1,
                              "type": "array"
                            },
                            "text": {
                              "description": "Greeting shown when the chat opens. Replaces Meta's default.",
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "text"
                          ],
                          "type": "object"
                        }
                      },
                      "type": "object"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "currency": {
                    "description": "ISO 4217 currency code matching the ad account's currency (e.g. `USD`).",
                    "maxLength": 3,
                    "minLength": 3,
                    "type": "string"
                  },
                  "customLocations": {
                    "description": "Point-radius geo (Meta `geo_locations.custom_locations`). Use for targeting a radius around a specific lat/long when no Meta city/region key fits. `distanceUnit` is required.",
                    "items": {
                      "properties": {
                        "address": {
                          "type": "string"
                        },
                        "distanceUnit": {
                          "enum": [
                            "mile",
                            "kilometer"
                          ],
                          "type": "string"
                        },
                        "latitude": {
                          "maximum": 90,
                          "minimum": -90,
                          "type": "number"
                        },
                        "longitude": {
                          "maximum": 180,
                          "minimum": -180,
                          "type": "number"
                        },
                        "name": {
                          "type": "string"
                        },
                        "radius": {
                          "exclusiveMinimum": 0,
                          "type": "number"
                        }
                      },
                      "required": [
                        "distanceUnit",
                        "latitude",
                        "longitude",
                        "radius"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "description": {
                    "description": "Link description, independent of `headline` and `body`: Meta's `link_data.description`, `video_data.link_description` on video, and the shared description of a `placementAssets` feed.",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "destination": {
                    "description": "Where the conversation opens when the ad is tapped. Set this OR `destinations`, not both.",
                    "enum": [
                      "whatsapp",
                      "messenger",
                      "instagram_direct"
                    ],
                    "type": "string"
                  },
                  "destinations": {
                    "description": "Two or three messaging apps on ONE ad set, like Ads Manager's \"all messaging apps\". Set this OR `destination`, not both. The ad set gets Meta's combined destination_type (e.g.",
                    "items": {
                      "enum": [
                        "whatsapp",
                        "messenger",
                        "instagram_direct"
                      ],
                      "type": "string"
                    },
                    "maxItems": 3,
                    "minItems": 2,
                    "type": "array",
                    "uniqueItems": true
                  },
                  "dsaBeneficiary": {
                    "description": "Legal entity that benefits from the ad. Required when targeting EU users (EU DSA, Article 26).",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "dsaPayor": {
                    "description": "Legal entity that pays for the ad. Can differ from `dsaBeneficiary` (for example, an agency paying for a client's ads). Same rules as `dsaBeneficiary`: required for EU targeting unless the ad account has a default payor.",
                    "maxLength": 100,
                    "type": "string"
                  },
                  "endDate": {
                    "description": "ISO 8601 date or date-time, read like `startDate`; a date-only value ends at 23:59:59 local. Required when `budgetType` is `lifetime`.",
                    "type": "string"
                  },
                  "excludedLocations": {
                    "additionalProperties": true,
                    "description": "Geo to exclude, same shape as POST /apis/v1/ads/create (countries, countryGroups, regions, cities, zips, places, neighborhoods, customLocations).",
                    "type": "object"
                  },
                  "existingCampaignId": {
                    "description": "Creates the new messaging ad set (and its ads) under this EXISTING Meta campaign instead of a new one, e.g. several audience ad sets under one campaign. To add ads to an existing ad set instead, use `adSetId`. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "pattern": "^\\d+$",
                    "type": "string"
                  },
                  "existingPostId": {
                    "description": "Alias of platformPostId, kept for existing callers. Sending both with different values is a 400.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "gender": {
                    "description": "Restrict the audience by gender (Meta `genders`). Omit or send all for everyone; all is ignored in adSetId attach mode. Stored on the ad and read back in `targeting.gender`.",
                    "enum": [
                      "all",
                      "male",
                      "female"
                    ],
                    "type": "string"
                  },
                  "headline": {
                    "description": "Single-creative shape only. Mutually exclusive with `creatives[]`. Required on a single image or video ad (including one built with `placementAssets`); not used by a `carouselCards` ad and not accepted with an existing post reference.",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "imageUrl": {
                    "description": "Image asset for single-creative shape. Mutually exclusive with `video` and with `creatives[]`. Required on the single-creative shape if neither `video` nor an existing post reference is supplied.",
                    "format": "uri",
                    "type": "string"
                  },
                  "incomeTier": {
                    "description": "Normalized household-income tier, same as POST /apis/v1/ads/create. Incompatible with housing, employment and credit specialAdCategories.",
                    "enum": [
                      "top_5",
                      "top_10",
                      "top_10_25",
                      "top_25_50"
                    ],
                    "type": "string"
                  },
                  "interests": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "languages": {
                    "description": "Audience languages (Meta `locales`). A bare ISO 639-1 code targets all regional variants (\"en\" = all English), a region-qualified code a specific one (\"en_GB\", \"pt_BR\"); unknown codes are rejected.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "metros": {
                    "description": "DMA / metro-area geo targeting. `key` is Meta's metro id (e.g. `DMA:807`).",
                    "items": {
                      "properties": {
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "name": {
                    "description": "Ad display name. Used to derive campaign / ad set names. On the multi-creative shape, each ad's Meta name gets a \" #N\" suffix (1-indexed) so Ads Manager shows them as a numbered batch.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "neighborhoods": {
                    "description": "Meta neighborhood keys (from GET /apis/v1/ads/targeting/search).",
                    "items": {
                      "properties": {
                        "key": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "objectStoryId": {
                    "description": "Messaging and CTWA only. Raw Facebook pageId_postId reference, used as object_story_id even with an Instagram account. Mutually exclusive with platformPostId and fresh creative fields.",
                    "pattern": "^\\d+_\\d+$",
                    "type": "string"
                  },
                  "objective": {
                    "description": "Defaults to `OUTCOME_ENGAGEMENT`. `OUTCOME_SALES` and `OUTCOME_LEADS` require additional account configuration (Dataset linked to the WABA for sales) and may be rejected by Meta if missing.",
                    "enum": [
                      "OUTCOME_ENGAGEMENT",
                      "OUTCOME_SALES",
                      "OUTCOME_LEADS"
                    ],
                    "type": "string"
                  },
                  "optimizeCardOrder": {
                    "description": "Only with `carouselCards` (a 400 without them). Single-creative shape; for `creatives[]` set it per entry. Sets the creative's `link_data.multi_share_optimized`. `false`: keeps the cards in the order given.",
                    "type": "boolean"
                  },
                  "pageId": {
                    "description": "Facebook Page the ad runs as, when the connection was granted several Pages. Defaults to the Page bound to the connection. Any Page granted to the connection is accepted; other ids answer 400 listing the granted Pages.",
                    "type": "string"
                  },
                  "placementAssets": {
                    "description": "A different image or video per placement on one messaging ad, e.g. a 4:5 image on Feed and a 9:16 image on Stories/Reels. Works on the single-creative shape and on attach (`adSetId`).",
                    "properties": {
                      "defaultImageUrl": {
                        "description": "Image mode. Catch-all image for any placement no rule matches. Required in image mode (Meta mandates a default rule).",
                        "format": "uri",
                        "type": "string"
                      },
                      "defaultThumbnailUrl": {
                        "description": "Video mode (optional). Poster image for the default video; Meta auto-generates one when omitted.",
                        "format": "uri",
                        "type": "string"
                      },
                      "defaultVideoUrl": {
                        "description": "Video mode. Catch-all video for any placement no rule matches. Required in video mode.",
                        "format": "uri",
                        "type": "string"
                      },
                      "rules": {
                        "description": "One entry per placement group you want to pin a specific asset to.",
                        "items": {
                          "properties": {
                            "body": {
                              "description": "One primary text pinned to this rule. Omit to inherit the top-level body.",
                              "minLength": 1,
                              "type": "string"
                            },
                            "description": {
                              "description": "One link description pinned to this rule. Omit to inherit the top-level description.",
                              "maxLength": 255,
                              "minLength": 1,
                              "type": "string"
                            },
                            "headline": {
                              "description": "One headline pinned to this rule. Omit to inherit the top-level headline.",
                              "maxLength": 255,
                              "minLength": 1,
                              "type": "string"
                            },
                            "imageUrl": {
                              "description": "Image mode. The image to deliver for this rule's placements.",
                              "format": "uri",
                              "type": "string"
                            },
                            "placements": {
                              "description": "Placements this asset is pinned to. At least one field must be set (an empty rule is invalid; that role is served by the default asset). Same enums as the top-level `placements` object.",
                              "properties": {
                                "audienceNetworkPositions": {
                                  "items": {
                                    "enum": [
                                      "classic",
                                      "rewarded_video"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "devicePlatforms": {
                                  "items": {
                                    "enum": [
                                      "mobile",
                                      "desktop"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "facebookPositions": {
                                  "items": {
                                    "enum": [
                                      "feed",
                                      "right_hand_column",
                                      "marketplace",
                                      "story",
                                      "search",
                                      "instream_video",
                                      "facebook_reels",
                                      "facebook_reels_overlay",
                                      "profile_feed",
                                      "notification"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "instagramPositions": {
                                  "items": {
                                    "enum": [
                                      "stream",
                                      "story",
                                      "explore",
                                      "explore_home",
                                      "reels",
                                      "profile_feed",
                                      "ig_search",
                                      "profile_reels"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "messengerPositions": {
                                  "items": {
                                    "enum": [
                                      "messenger_home",
                                      "sponsored_messages",
                                      "story"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "publisherPlatforms": {
                                  "items": {
                                    "enum": [
                                      "facebook",
                                      "instagram",
                                      "threads",
                                      "messenger",
                                      "audience_network",
                                      "whatsapp",
                                      "meta"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "threadsPositions": {
                                  "items": {
                                    "enum": [
                                      "threads_stream"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                },
                                "whatsappPositions": {
                                  "items": {
                                    "enum": [
                                      "status"
                                    ],
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "thumbnailUrl": {
                              "description": "Video mode (optional). Poster image for this rule's video; auto-generated when omitted.",
                              "format": "uri",
                              "type": "string"
                            },
                            "videoUrl": {
                              "description": "Video mode. The video to deliver for this rule's placements.",
                              "format": "uri",
                              "type": "string"
                            }
                          },
                          "required": [
                            "placements"
                          ],
                          "type": "object"
                        },
                        "maxItems": 10,
                        "minItems": 1,
                        "type": "array"
                      }
                    },
                    "required": [
                      "rules"
                    ],
                    "type": "object"
                  },
                  "placements": {
                    "description": "Manual ad placements on the shared ad set. Omit for automatic placements.",
                    "properties": {
                      "audienceNetworkPositions": {
                        "items": {
                          "enum": [
                            "classic",
                            "rewarded_video"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "devicePlatforms": {
                        "description": "Restrict by device. Omit to deliver on both mobile and desktop.",
                        "items": {
                          "enum": [
                            "mobile",
                            "desktop"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "facebookPositions": {
                        "items": {
                          "enum": [
                            "feed",
                            "right_hand_column",
                            "marketplace",
                            "story",
                            "search",
                            "instream_video",
                            "facebook_reels",
                            "facebook_reels_overlay",
                            "profile_feed",
                            "notification"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "instagramPositions": {
                        "items": {
                          "enum": [
                            "stream",
                            "story",
                            "explore",
                            "explore_home",
                            "reels",
                            "profile_feed",
                            "ig_search",
                            "profile_reels"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "messengerPositions": {
                        "items": {
                          "enum": [
                            "messenger_home",
                            "sponsored_messages",
                            "story"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "publisherPlatforms": {
                        "description": "Top-level platforms to deliver on. A position field below is only honoured when its parent platform is included here.",
                        "items": {
                          "enum": [
                            "facebook",
                            "instagram",
                            "threads",
                            "messenger",
                            "audience_network",
                            "whatsapp",
                            "meta"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "threadsPositions": {
                        "items": {
                          "enum": [
                            "threads_stream"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "whatsappPositions": {
                        "items": {
                          "enum": [
                            "status"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "places": {
                    "description": "Meta place keys (from GET /apis/v1/ads/targeting/search).",
                    "items": {
                      "properties": {
                        "key": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "platformPostId": {
                    "description": "Messaging and CTWA only. Platform post or reel ID, the same input boostPost takes as platformPostId. Mutually exclusive with objectStoryId and fresh creative fields. Facebook IDs become object_story_id.",
                    "minLength": 1,
                    "type": "string"
                  },
                  "rawTargeting": {
                    "additionalProperties": true,
                    "description": "Meta targeting spec sent as the BASE layer of the ad set's `targeting`, exactly as POST /apis/v1/ads/create does.",
                    "type": "object"
                  },
                  "regionalRegulatedCategories": {
                    "description": "Meta only. Regional regulation categories required when the ad set targets certain countries (e.g.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "regionalRegulationIdentities": {
                    "additionalProperties": {
                      "type": [
                        "string",
                        "integer"
                      ]
                    },
                    "description": "Meta only. Verified identity IDs of the beneficiary and payer for each declared regionalRegulatedCategories value. Ignored when adSetId adds the ad to an existing ad set.",
                    "type": "object"
                  },
                  "regions": {
                    "description": "Region / state-level geo targeting. `key` is Meta's region ID (lookupable via GET /apis/v1/ads/targeting/search?type=region).",
                    "items": {
                      "properties": {
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "roasAverageFloor": {
                    "description": "Decimal ROAS multiplier (e.g. `2.0` = 2.0× ROAS floor). Required when `bidStrategy` is `LOWEST_COST_WITH_MIN_ROAS`; rejected otherwise. Meta enforces its own upper bound server-side.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "savedTargetingId": {
                    "description": "ID of a saved_targeting audience (POST /apis/v1/ads/audiences), expanded as the base targeting. Precedence: savedTargetingId, then `targeting`, then the flat fields. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "specialAdCategories": {
                    "description": "Meta special ad categories on the new campaign.",
                    "items": {
                      "enum": [
                        "HOUSING",
                        "EMPLOYMENT",
                        "CREDIT",
                        "ISSUES_ELECTIONS_POLITICS",
                        "FINANCIAL_PRODUCTS_SERVICES",
                        "ONLINE_GAMBLING_AND_GAMING"
                      ],
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "specialAdCategoryCountry": {
                    "description": "Countries the special ad category applies to. Requires specialAdCategories.",
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "startDate": {
                    "description": "When the ad set starts delivering. ISO 8601 date or date-time.",
                    "type": "string"
                  },
                  "status": {
                    "description": "Defaults to `ACTIVE`. `PAUSED` pauses only the top-most object this call creates: the new campaign (ad set and ads switched on), or, with `adSetId`, the new ads themselves.",
                    "enum": [
                      "ACTIVE",
                      "PAUSED"
                    ],
                    "type": "string"
                  },
                  "targeting": {
                    "description": "Normalized, platform-agnostic ad-targeting spec. Every field is optional; an empty object targets the platform's default broadest audience.",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "tracking": {
                    "description": "Ad tracking. Meta, plus `urlTags` on ChatGPT (OpenAI) and `pixelId` on Reddit. Meta: attaches pixel measurement to the ad regardless of the optimization goal (the \"Website events\" tracking row in Ads Manager).",
                    "properties": {
                      "pixelId": {
                        "description": "Meta Pixel ID to attach for offsite-conversion measurement, or the Reddit pixel of the new ad group.",
                        "type": "string"
                      },
                      "urlTags": {
                        "description": "Click-URL params. Meta: stored on the creative as `url_tags` and returned by GET /apis/v1/ads/{adId}/tracking-tags.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "value": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key",
                            "value"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "userDevice": {
                    "description": "Meta `user_device`.",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "userOs": {
                    "description": "Meta `user_os`, e.g. [\"iOS_ver_14.0_and_above\"].",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "validateOnly": {
                    "description": "Dry-runs the ad on Meta with execution_options validate_only, as ONE inline campaign + ad set + creative + ad (or creative + ad on the existing ad set with `adSetId`). Nothing is uploaded, created or stored; media is checked by URL.",
                    "type": "boolean"
                  },
                  "video": {
                    "description": "Video creative for single-creative shape. Mutually exclusive with `imageUrl` and with `creatives[]`. Required on the single-creative shape if neither `imageUrl` nor an existing post reference is supplied.",
                    "properties": {
                      "id": {
                        "description": "Reuse a video already uploaded to this ad account (list them with GET /apis/v1/ads/videos) instead of re-uploading. Wins over `url`. Provide either `url` or `id`.",
                        "type": "string"
                      },
                      "thumbnailUrl": {
                        "description": "OPTIONAL: when omitted, the poster is auto-generated from Meta's own preferred video thumbnail. When Meta produces no candidate the request fails with a 502 platform_error (reason: video_thumbnail_unavailable).",
                        "format": "uri",
                        "type": "string"
                      },
                      "url": {
                        "description": "Public URL of the video to upload. Provide either `url` or `id`.",
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "welcomeMessage": {
                    "description": "Custom chat welcome message (Meta's `page_welcome_message`, \"Mensaje de bienvenida\" / \"Mensaje predefinido\" in Ads Manager). Single-creative shape only; for `creatives[]` set it per entry.",
                    "properties": {
                      "prefillText": {
                        "description": "Message put into the user's text input, ready to send. Replaces Meta's default (\"Hi! I want more info.\"). Lets one ad steer the opening message toward what it promotes (e.g. a specific product). Exactly one of prefillText or quickReplies.",
                        "minLength": 1,
                        "type": "string"
                      },
                      "quickReplies": {
                        "description": "Tappable chips under the greeting instead of a prefilled message. Exactly one of prefillText or quickReplies. Put your own campaign or ad key in each payload.",
                        "items": {
                          "properties": {
                            "payload": {
                              "maxLength": 1000,
                              "minLength": 1,
                              "type": "string"
                            },
                            "title": {
                              "description": "Chip label the person taps.",
                              "maxLength": 20,
                              "minLength": 1,
                              "type": "string"
                            }
                          },
                          "required": [
                            "payload",
                            "title"
                          ],
                          "type": "object"
                        },
                        "maxItems": 13,
                        "minItems": 1,
                        "type": "array"
                      },
                      "text": {
                        "description": "Greeting shown when the chat opens. Replaces Meta's default (\"Hi! Can we help you?\").",
                        "minLength": 1,
                        "type": "string"
                      }
                    },
                    "required": [
                      "text"
                    ],
                    "type": "object"
                  },
                  "whatsappPhoneNumber": {
                    "description": "WhatsApp only. Optional E.164 number already paired with the Facebook Page. Omit to let Meta select the paired number. Sent to the creative CTA and, when creating a new ad set, its promoted_object.",
                    "pattern": "^\\+[1-9]\\d{6,14}$",
                    "type": "string"
                  },
                  "workEmployers": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "workIndustries": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "workPositions": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "workflowId": {
                    "description": "A workflow in the ad account's profile, stored on the ad. 404 when no such workflow exists in the profile.",
                    "pattern": "^[a-fA-F0-9]{24}$",
                    "type": "string"
                  },
                  "zips": {
                    "description": "ZIP / postal-code geo targeting. `key` is the platform's postal id resolved via /apis/v1/ads/targeting/search.",
                    "items": {
                      "properties": {
                        "key": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  }
                },
                "required": [
                  "adAccountId",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "results": {
                      "items": {
                        "properties": {
                          "node": {
                            "enum": [
                              "campaign",
                              "adSet",
                              "creative",
                              "ad"
                            ],
                            "type": "string"
                          },
                          "reason": {
                            "description": "On unverified: why Meta could not dry-run this node although the other nodes passed.",
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "validated",
                              "skipped",
                              "unverified"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "node",
                          "status"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "validateOnly": {
                      "description": "Always true.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "message",
                    "results",
                    "validateOnly"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "`validateOnly: true` only. Meta accepted every node; nothing was created."
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "description": "Response returned by `POST /apis/v1/ads/ctwa` when the request used the single-creative shape (top-level headline / body / imageUrl|video). `adType` is the union discriminator.",
                      "properties": {
                        "ad": {
                          "description": "The persisted Ad document.",
                          "type": "object"
                        },
                        "adType": {
                          "enum": [
                            "single"
                          ],
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "warnings": {
                          "description": "Present when Meta created the ad set differently from the request:",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "ad",
                        "adType",
                        "message"
                      ],
                      "type": "object"
                    },
                    {
                      "description": "Response returned by `POST /apis/v1/ads/ctwa` when the request used the multi-creative shape (`creatives[]`). N persisted Ad documents share the returned `platformCampaignId` and `platformAdSetId`. `adType` is the union discriminator.",
                      "properties": {
                        "adType": {
                          "enum": [
                            "multi"
                          ],
                          "type": "string"
                        },
                        "ads": {
                          "description": "The persisted Ad documents (one per creative), all sharing the same `platformCampaignId` and `platformAdSetId`.",
                          "items": {
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "message": {
                          "type": "string"
                        },
                        "platformAdSetId": {
                          "type": "string"
                        },
                        "platformCampaignId": {
                          "type": "string"
                        },
                        "warnings": {
                          "description": "Present when Meta created the ad set differently from the request:",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "adType",
                        "ads",
                        "message",
                        "platformAdSetId",
                        "platformCampaignId"
                      ],
                      "type": "object"
                    }
                  ]
                }
              }
            },
            "description": "Ad(s) created and submitted for review."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create messaging ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_messaging_ad@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6a28bbd0af6e7fa3fe587f49078648b81ba784e629201a2365a5ccc8d0efe236"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_messaging",
          "method": "POST",
          "path": "/apis/v1/ads/messaging"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_messaging"
      }
    },
    "/apis/v1/ads/page-users": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Removes a person's access to a Facebook Page assigned through your business portfolio.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_page_users",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Facebook Page id.",
            "in": "query",
            "name": "pageId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Business-scoped user id.",
            "in": "query",
            "name": "userId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "pageId": {
                      "type": "string"
                    },
                    "removed": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "User removed"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Remove a user from a Page",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.remove_page_user@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e8e3469184ac5a1beb0b18756c8644125160e8eea9d77d16f1d84196a9e2d6eb"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_page_users",
          "method": "DELETE",
          "path": "/apis/v1/ads/page-users"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_page_users"
      },
      "get": {
        "description": "Ad Accounts. Read only. Lists the people in a business portfolio who are assigned to a Facebook Page it owns or was shared as a partner.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_page_users",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Facebook Page id.",
            "in": "query",
            "name": "pageId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Business portfolio whose people to list.",
            "in": "query",
            "name": "businessId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "businessId": {
                      "type": "string"
                    },
                    "pageId": {
                      "type": "string"
                    },
                    "users": {
                      "items": {
                        "properties": {
                          "id": {
                            "description": "Business-scoped user id.",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "tasks": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Assigned users"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Page users of a business",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_page_users@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a5aaae8dccd3a05274351a7da331615612d50feed939d038a32adb55443e3b22"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_page_users",
          "method": "GET",
          "path": "/apis/v1/ads/page-users"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_page_users"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Gives a person in your business portfolio tasks on a Facebook Page, such as advertising, so they can run ads for it. The Page can be one the portfolio owns or was granted as a partner. Meta does not assign partner admins automatically, so after an owner shares a Page the partner calls this for the people whose tokens will advertise for it. `ADVERTISE` is what ad creation needs.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_page_users",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "businessId": "1234567890123",
                "connectionId": "adc_7f3k2m9q",
                "pageId": "123456789012345",
                "tasks": [
                  "ADVERTISE",
                  "ANALYZE"
                ],
                "userId": "1122334455"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "businessId": {
                    "description": "Business portfolio the user belongs to.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "pageId": {
                    "description": "Facebook Page id.",
                    "type": "string"
                  },
                  "tasks": {
                    "items": {
                      "enum": [
                        "MANAGE",
                        "CREATE_CONTENT",
                        "MODERATE",
                        "MESSAGING",
                        "ADVERTISE",
                        "ANALYZE"
                      ],
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "userId": {
                    "description": "Business-scoped user id from GET /apis/v1/ads/businesses/users.",
                    "type": "string"
                  }
                },
                "required": [
                  "businessId",
                  "pageId",
                  "tasks",
                  "userId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "businessId": {
                      "type": "string"
                    },
                    "pageId": {
                      "type": "string"
                    },
                    "user": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "tasks": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "User assigned"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Assign a user to a Page",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.assign_page_user@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "df741a51e80023ad222dbf750f8155f53723b884aa90c64d7f988c9681ff7d32"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_page_users",
          "method": "POST",
          "path": "/apis/v1/ads/page-users"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_page_users"
      }
    },
    "/apis/v1/ads/partnership-content": {
      "get": {
        "description": "Ad Creatives. Read only. Lists a creator's Instagram posts you can run as Partnership Ads, looked up by creator or post link (private beta). Lists creator Instagram posts available to the advertiser for Partnership Ads. Supply creatorUsername or postUrl. Requires instagram_branded_content_ads_brand permission and an advertiser Instagram Business Account.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_partnership_content",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Creator username. Required unless postUrl is supplied.",
            "in": "query",
            "name": "creatorUsername",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Instagram post permalink. Required unless creatorUsername is supplied.",
            "in": "query",
            "name": "postUrl",
            "required": false,
            "schema": {
              "format": "uri",
              "type": "string"
            }
          },
          {
            "description": "Return only creators with account-level permission.",
            "in": "query",
            "name": "onlyAllowlisted",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "media": {
                      "items": {
                        "properties": {
                          "eligibilityErrors": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "hasPermissionForPartnershipAd": {
                            "type": "boolean"
                          },
                          "id": {
                            "type": "string"
                          },
                          "isCreatorAllowlisted": {
                            "type": "boolean"
                          },
                          "ownerId": {
                            "type": "string"
                          },
                          "permalink": {
                            "type": "string"
                          },
                          "recommendedCampaignObjectives": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Advertisable Instagram media."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List partnership ad content",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_partnership_ad_content@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "d46905b7dc3bee13ccc34faa7da88b12e2630d6d3434ecc250693ebb338231f7"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_partnership_content",
          "method": "GET",
          "path": "/apis/v1/ads/partnership-content"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_partnership_content"
      }
    },
    "/apis/v1/ads/partnership-permissions": {
      "get": {
        "description": "Ad Creatives. Read only. Lists the creators who have granted, or have pending, permission for your Instagram account to run Partnership Ads with them (private beta). Lists granted or pending creator permissions for the advertiser Instagram Business Account. Requires instagram_branded_content_ads_brand permission.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_partnership_permissions",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Filter by creator username.",
            "in": "query",
            "name": "creatorUsername",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "permissions": {
                      "items": {
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "permissionType": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Partnership permissions."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List partnership permissions",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_partnership_ad_permissions@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "af47d3667105041235c91a389334e18e551fe86cac4e9dcc3d07106af15d52a4"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_partnership_permissions",
          "method": "GET",
          "path": "/apis/v1/ads/partnership-permissions"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_partnership_permissions"
      },
      "post": {
        "description": "Ad Creatives. Changes the ad account without starting or raising spend; audited. Asks a creator for permission to run Partnership Ads with their content, or revokes it (private beta). Requests permission from a creator or revokes it when revoke is true. Requests require the creator to approve in Instagram. Requires instagram_branded_content_ads_brand permission.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_partnership_permissions",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "creatorUsername": "example_creator",
                "revoke": false
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "creatorUsername": {
                    "minLength": 1,
                    "type": "string"
                  },
                  "revoke": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "creatorUsername"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "permission": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "permissionType": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Partnership permission state."
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "permission": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "permissionType": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Partnership permission state."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Set partnership permission",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.set_partnership_ad_permission@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "e184ca09a0a34d71e2ec1ebd897e6c23b6b03e27c1e86817db803462004b8fec"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_partnership_permissions",
          "method": "POST",
          "path": "/apis/v1/ads/partnership-permissions"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_partnership_permissions"
      }
    },
    "/apis/v1/ads/pixels": {
      "get": {
        "description": "Ad Accounts. Read only. Lists pixels and their supported optimization events for a connected TikTok Ads account. The advertiser defaults to the first advertiser on the connection. Reconnect if Pixel Management permission has not been granted.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_pixels",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (TikTok advertiser id, digits only). Defaults to the first advertiser on the connection.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "advertiserId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter by a Pixel Code.",
            "in": "query",
            "name": "code",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "advertiserId": {
                      "type": "string"
                    },
                    "pixels": {
                      "items": {
                        "properties": {
                          "eventDetails": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "events": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "name": {
                            "type": "string"
                          },
                          "pixelCode": {
                            "type": "string"
                          },
                          "pixelId": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "TikTok pixels."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List TikTok ad pixels",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_tik_tok_ad_pixels@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "2ace9da99e06b70f8629e73d058248743feaeb60f62a1b288d127305cdcffbf5"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_pixels",
          "method": "GET",
          "path": "/apis/v1/ads/pixels"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_pixels"
      }
    },
    "/apis/v1/ads/preview": {
      "post": {
        "description": "Ad Creatives. Read only. Shows how a Meta creative will look in each placement before you create the ad, as embeddable previews. Renders how a creative would look per placement BEFORE any ad exists, via Meta's `/generatepreviews`. Provide exactly one creative source: `existingCreativeId` or `creativeSpec`. Each preview is an HTML `` snippet embeddable directly. Unknown `formats` values return Meta's 400 verbatim.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_preview",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account id (Meta act_, Google customer id, LinkedIn account id, ...).",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "creativeSpec": {
                    "additionalProperties": true,
                    "description": "Raw Meta creative spec forwarded to /generatepreviews. Mutually exclusive with existingCreativeId.",
                    "type": "object"
                  },
                  "existingCreativeId": {
                    "description": "Preview an existing ad-account creative by id. Mutually exclusive with creativeSpec.",
                    "type": "string"
                  },
                  "formats": {
                    "description": "Meta ad_format values, one preview per format. Defaults to [DESKTOP_FEED_STANDARD].",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "adAccountId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "previews": {
                      "items": {
                        "properties": {
                          "format": {
                            "type": "string"
                          },
                          "html": {
                            "description": "Meta's snippet; null when Meta returned no preview for the format.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Rendered previews"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Render pre-create ad previews",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.generate_ad_previews@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "8c16d6b3713f5338f1cd14689c4d3b4266f24c5547718411e057991879ebff77"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_preview",
          "method": "POST",
          "path": "/apis/v1/ads/preview"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_preview"
      }
    },
    "/apis/v1/ads/recommendations": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists Google's optimization suggestions for an ad account, with the estimated impact of each. ### What each recommendation includes type estimated impact (base vs potential metrics, cost in account currency units) the campaign, ad group or budget they target the type-specific payload Google returns (`details`, in Google's own shape with micros) Filter by campaignId and types.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_recommendations",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Google customer id, digits only. Defaults to the connection's only customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for consistency with other Google endpoints.",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only recommendations targeting this campaign. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Google RecommendationType values, for example CAMPAIGN_BUDGET,KEYWORD,SET_TARGET_CPA.",
            "in": "query",
            "name": "types",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "cachedAt": {
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "recommendations": {
                      "items": {
                        "properties": {
                          "adGroupId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignBudgetId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignIds": {
                            "description": "Every campaign the recommendation targets (several for account-level types).",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "details": {
                            "description": "The type-specific recommendation payload exactly as Google returns it (camelCase, amounts in micros), for example recommendedTargetCpaMicros or budgetOptions.",
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "dismissed": {
                            "type": "boolean"
                          },
                          "id": {
                            "type": "string"
                          },
                          "impact": {
                            "description": "Google's estimate over its own window. Null when Google gives none for the type.",
                            "properties": {
                              "base": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "potential": {
                                "additionalProperties": true,
                                "type": "object"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "resourceName": {
                            "description": "customers/{customerId}/recommendations/{id}. Pass it to apply or dismiss.",
                            "type": "string"
                          },
                          "type": {
                            "description": "Google RecommendationType, such as CAMPAIGN_BUDGET, KEYWORD or SET_TARGET_CPA.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "adGroupId",
                          "campaignBudgetId",
                          "campaignId",
                          "campaignIds",
                          "details",
                          "dismissed",
                          "id",
                          "impact",
                          "resourceName",
                          "type"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "stale": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "adAccountId",
                    "cachedAt",
                    "recommendations",
                    "stale"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Recommendations."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List Google Ads recommendations",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_google_recommendations@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1173c0ca390a5d83bfe688f43c692ff6971a082b3a53d7a316f26ca0c9b76ea0"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_recommendations",
          "method": "GET",
          "path": "/apis/v1/ads/recommendations"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_recommendations"
      }
    },
    "/apis/v1/ads/recommendations/apply": {
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Applies platform recommendations, which can raise budgets and bids. Applies Google's optimization suggestions to an ad account, using Google's values or your own; the changes cannot be undone. Apply up to 100 recommendations. This changes the account (budgets, bidding, keywords, assets) and is not reversible or idempotent. Google offers no validate-only mode for it. Items run in partial-failure mode, so one stale recommendation does not block the rest.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_recommendations_apply",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "9122445560",
                "connectionId": "adc_7f3k2m9q",
                "recommendations": [
                  {
                    "resourceName": "customers/9122445560/recommendations/NjgzMzAxODc4NS0yNDEtMTc5MDQ3NTQyNjU5Ni0rMjM1MjA5NjcxNjctMA"
                  },
                  {
                    "parameters": {
                      "campaignBudget": {
                        "newBudgetAmountMicros": "150000000"
                      }
                    },
                    "resourceName": "customers/9122445560/recommendations/NjgzMzAxODc4NS0yMjgtMTc5MDQyNDE5NjUwNS0rMTU3NjMyNzU3ODk"
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Google customer id, digits only. Required when the connection has several customers.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "recommendations": {
                    "items": {
                      "properties": {
                        "parameters": {
                          "additionalProperties": true,
                          "description": "One key, such as campaignBudget, keyword, textAd, targetCpaOptIn, targetRoasOptIn, callAsset, calloutAsset, sitelinkAsset, moveUnusedBudget, responsiveSearchAd, responsiveSearchAdAsset, responsiveSearchAdImproveAdStrength…",
                          "type": "object"
                        },
                        "resourceName": {
                          "description": "Recommendation resource name from the list, or its id.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "resourceName"
                      ],
                      "type": "object"
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "recommendations"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "results": {
                      "items": {
                        "properties": {
                          "error": {
                            "description": "Google's message when status is failed.",
                            "type": "string"
                          },
                          "resourceName": {
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "applied",
                              "dismissed",
                              "failed"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "resourceName",
                          "status"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "adAccountId",
                    "results"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Per-recommendation outcome. A failed item does not stop the others."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Apply Google Ads recommendations",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.apply_google_recommendations@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6dd4fea91896cf5cdd5a80ad93bb4aec46212de0a4a65edee99d13fbd99c2835"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_recommendations_apply",
          "method": "POST",
          "path": "/apis/v1/ads/recommendations/apply"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_recommendations_apply"
      }
    },
    "/apis/v1/ads/recommendations/dismiss": {
      "post": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Dismisses Google optimization suggestions so Google stops showing them. Dismiss up to 100 recommendations so Google stops suggesting them. Items run in partial-failure mode.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_recommendations_dismiss",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "resourceNames": [
                  "example"
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Google customer id, digits only. Required when the connection has several customers.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "resourceNames": {
                    "description": "Recommendation resource names from the list, or their ids.",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "resourceNames"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "results": {
                      "items": {
                        "properties": {
                          "error": {
                            "description": "Google's message when status is failed.",
                            "type": "string"
                          },
                          "resourceName": {
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "applied",
                              "dismissed",
                              "failed"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "resourceName",
                          "status"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "adAccountId",
                    "results"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Per-recommendation outcome. A failed item does not stop the others."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Dismiss Google Ads recommendations",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.dismiss_google_recommendations@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "77e6b444fce75f2d784a3172623b150732aa1e9471321615f138a8d25a29a148"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_recommendations_dismiss",
          "method": "POST",
          "path": "/apis/v1/ads/recommendations/dismiss"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_recommendations_dismiss"
      }
    },
    "/apis/v1/ads/rf-predictions": {
      "post": {
        "description": "Reach and Frequency. Read only. Quotes the reach or budget for a Meta reach and frequency campaign over a date range, without buying anything. This is a QUOTE: nothing is bought and no ad entities are created. Provide a date range plus exactly one of: `budgetAmount`: Meta predicts reach `reach`: Meta predicts the budget The response carries the estimate and its allowed bounds (min/max budget and reach). ### Buying\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_rf_predictions",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "endDate": "2026-12-01T09:00:00Z",
                "startDate": "2026-12-01T09:00:00Z"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account id (Meta act_, Google customer id, LinkedIn account id, ...).",
                    "type": "string"
                  },
                  "budgetAmount": {
                    "description": "Whole currency units. Exactly one of budgetAmount / reach.",
                    "type": "number"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "endDate": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "frequencyCap": {
                    "description": "Max impressions per person over the window.",
                    "maximum": 90,
                    "minimum": 1,
                    "type": "integer"
                  },
                  "placements": {
                    "description": "Meta placements object (same shape as /apis/v1/ads/create's `placements`).",
                    "type": "object"
                  },
                  "reach": {
                    "description": "Target unique reach. Exactly one of budgetAmount / reach.",
                    "type": "integer"
                  },
                  "startDate": {
                    "description": "Campaign window start (must be in the future).",
                    "format": "date-time",
                    "type": "string"
                  },
                  "targeting": {
                    "description": "Canonical camelCase TargetingSpec (same shape as /apis/v1/ads/create's `targeting`). Defaults to countries: [US].",
                    "type": "object"
                  }
                },
                "required": [
                  "adAccountId",
                  "endDate",
                  "startDate"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "prediction": {
                      "description": "A Meta Reach & Frequency prediction. Money values in whole units of the ad account currency.",
                      "properties": {
                        "budget": {
                          "description": "Quoted (or provided) lifetime budget for the window.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "expiresAt": {
                          "description": "When the reservation's locked price expires (set after reserving).",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "frequencyCap": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "impressions": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "maxBudget": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "maxReach": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "minBudget": {
                          "description": "Meta's allowed lower bound for this spec.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "minReach": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "predictionId": {
                          "type": "string"
                        },
                        "reach": {
                          "description": "Predicted (or requested) unique reach.",
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "startTime": {
                          "description": "Unix seconds; the reserved window the R&F ad set will run on.",
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "status": {
                          "description": "ready | pending | failed:",
                          "type": "string"
                        },
                        "stopTime": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Prediction created (usually ready within seconds)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create reach-frequency prediction",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_rf_prediction@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "537d6dd2c83d61834ea36c98f779e336776ea78538b5dfe0a30c998f83aa1658"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_rf_predictions",
          "method": "POST",
          "path": "/apis/v1/ads/rf-predictions"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_rf_predictions"
      }
    },
    "/apis/v1/ads/rf-predictions/{predictionId}": {
      "delete": {
        "description": "Reach and Frequency. Changes the ad account without starting or raising spend; audited. Cancels a Meta reach and frequency reservation, releasing its locked price and inventory. Unreserved predictions expire on their own.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_rf_predictions_predictionid",
        "parameters": [
          {
            "in": "path",
            "name": "predictionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "description": "Reservation cancelled"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Cancel reach-frequency booking",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.cancel_rf_reservation@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1dd994fff414d9a2462f90905af8fbc83d6e7ae4c78f9e971fe8f8b0a376ca38"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_rf_predictions_predictionid",
          "method": "DELETE",
          "path": "/apis/v1/ads/rf-predictions/{predictionId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_rf_predictions_predictionid"
      },
      "get": {
        "description": "Reach and Frequency. Read only. Shows a Meta reach and frequency prediction, with its estimate and status.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_rf_predictions_predictionid",
        "parameters": [
          {
            "in": "path",
            "name": "predictionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "prediction": {
                      "description": "A Meta Reach & Frequency prediction. Money values in whole units of the ad account currency.",
                      "properties": {
                        "budget": {
                          "description": "Quoted (or provided) lifetime budget for the window.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "expiresAt": {
                          "description": "When the reservation's locked price expires (set after reserving).",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "frequencyCap": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "impressions": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "maxBudget": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "maxReach": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "minBudget": {
                          "description": "Meta's allowed lower bound for this spec.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "minReach": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "predictionId": {
                          "type": "string"
                        },
                        "reach": {
                          "description": "Predicted (or requested) unique reach.",
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "startTime": {
                          "description": "Unix seconds; the reserved window the R&F ad set will run on.",
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "status": {
                          "description": "ready | pending | failed:",
                          "type": "string"
                        },
                        "stopTime": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Prediction status and estimates"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get reach-frequency prediction",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_rf_prediction@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "8a6d7e0893fd585178bade3ab21d00c4b32d204a4e7cbf56c89c90abf97d322b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_rf_predictions_predictionid",
          "method": "GET",
          "path": "/apis/v1/ads/rf-predictions/{predictionId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_rf_predictions_predictionid"
      }
    },
    "/apis/v1/ads/rf-predictions/{predictionId}/reserve": {
      "post": {
        "description": "Reach and Frequency. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Reserves reach-and-frequency inventory, a commitment to buy it. Locks the quoted price and inventory of a Meta reach and frequency prediction so you can launch a campaign on it. Locks the quoted price + inventory until the returned `expiresAt` and mints a NEW prediction id. Pass that RESERVED id (not the original) as `rfPredictionId` on POST /apis/v1/ads/create. Release an unused reservation via DELETE.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_rf_predictions_predicti_26b922",
        "parameters": [
          {
            "in": "path",
            "name": "predictionId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  }
                },
                "required": [
                  "adAccountId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "prediction": {
                      "description": "A Meta Reach & Frequency prediction. Money values in whole units of the ad account currency.",
                      "properties": {
                        "budget": {
                          "description": "Quoted (or provided) lifetime budget for the window.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "expiresAt": {
                          "description": "When the reservation's locked price expires (set after reserving).",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "frequencyCap": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "impressions": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "maxBudget": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "maxReach": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "minBudget": {
                          "description": "Meta's allowed lower bound for this spec.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "minReach": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "predictionId": {
                          "type": "string"
                        },
                        "reach": {
                          "description": "Predicted (or requested) unique reach.",
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "startTime": {
                          "description": "Unix seconds; the reserved window the R&F ad set will run on.",
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "status": {
                          "description": "ready | pending | failed:",
                          "type": "string"
                        },
                        "stopTime": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Reserved; `prediction.predictionId` is the new RESERVED id"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Reserve reach-frequency inventory",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.reserve_rf_prediction@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "5de10fc8bbde4396c6d61e11cf672bcd490295b3802dff23d4e3311455c36ae3"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_rf_predictions_predicti_26b922",
          "method": "POST",
          "path": "/apis/v1/ads/rf-predictions/{predictionId}/reserve"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_rf_predictions_predicti_26b922"
      }
    },
    "/apis/v1/ads/rules": {
      "get": {
        "description": "Ad Rules. Read only. Lists the ad rules on the profiles your key can reach, newest first.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_rules",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Only rules watching this platform ad account.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "skip",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "rules": {
                      "items": {
                        "properties": {
                          "actions": {
                            "description": "Each type at most once, and at most one of `pause`, `activate` and `adjust_budget`.",
                            "items": {
                              "oneOf": [
                                {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                {
                                  "additionalProperties": true,
                                  "type": "object"
                                }
                              ]
                            },
                            "minItems": 1,
                            "type": "array"
                          },
                          "adAccountId": {
                            "description": "Platform ad account ID.",
                            "type": "string"
                          },
                          "campaignIds": {
                            "description": "Platform campaign IDs the rule is limited to. Null checks the whole ad account.",
                            "items": {
                              "type": "string"
                            },
                            "type": [
                              "array",
                              "null"
                            ]
                          },
                          "conditions": {
                            "description": "Every condition must hold for an object to match. A rate with no denominator (a CPA with no conversions) never matches.",
                            "properties": {
                              "all": {
                                "items": {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                "maxItems": 10,
                                "minItems": 1,
                                "type": "array"
                              }
                            },
                            "required": [
                              "all"
                            ],
                            "type": "object"
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "cooldownMinutes": {
                            "type": "integer"
                          },
                          "createdAt": {
                            "format": "date-time",
                            "type": "string"
                          },
                          "enabled": {
                            "type": "boolean"
                          },
                          "id": {
                            "type": "string"
                          },
                          "lastRunAt": {
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "level": {
                            "description": "Whether the rule checks campaigns, ad sets or single ads. Each one is evaluated on its own.",
                            "enum": [
                              "campaign",
                              "adset",
                              "ad"
                            ],
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "nextRunAt": {
                            "description": "Null while the rule is disabled.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platform": {
                            "description": "Ad platform, for example `facebook` (Meta) or `google`.",
                            "type": "string"
                          },
                          "schedule": {
                            "properties": {
                              "everyMinutes": {
                                "description": "How often the rule runs, in minutes.",
                                "enum": [
                                  60,
                                  180,
                                  360,
                                  720,
                                  1440
                                ],
                                "type": "integer"
                              }
                            },
                            "required": [
                              "everyMinutes"
                            ],
                            "type": "object"
                          },
                          "updatedAt": {
                            "format": "date-time",
                            "type": "string"
                          }
                        },
                        "required": [
                          "actions",
                          "adAccountId",
                          "campaignIds",
                          "conditions",
                          "cooldownMinutes",
                          "createdAt",
                          "enabled",
                          "id",
                          "lastRunAt",
                          "level",
                          "name",
                          "nextRunAt",
                          "platform",
                          "schedule",
                          "updatedAt"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "rules"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Rules"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List ad rules",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_rules@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "f00301e80d1e1f954040cf729857b4f9382c79decd433fd366e244233517a6ff"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_rules",
          "method": "GET",
          "path": "/apis/v1/ads/rules"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_rules"
      },
      "post": {
        "description": "Ad Rules. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates an automated rule that can change budgets and turn delivery on or off. Creates a rule that checks the campaigns or ad sets of one ad account on a schedule and acts on each one that meets every condition. Rules support Meta, Google, TikTok, LinkedIn, Pinterest, X and Reddit ads connections. Use `POST /apis/v1/ads/rules/{ruleId}/preview` to see what a rule would match before enabling it. ### Evaluation ### Actions `pause` `activate` `adjust_budget` ### Cooldown\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_rules",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "actions": [
                  {
                    "type": "notify"
                  }
                ],
                "adAccountId": "act_1234567890",
                "conditions": {
                  "all": [
                    {
                      "metric": "spend",
                      "op": ">",
                      "value": 10,
                      "window": "today"
                    }
                  ]
                },
                "connectionId": "adc_7f3k2m9q",
                "level": "campaign",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "actions": {
                    "description": "Each type at most once, and at most one of `pause`, `activate` and `adjust_budget`.",
                    "items": {
                      "oneOf": [
                        {
                          "properties": {
                            "type": {
                              "enum": [
                                "notify"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "type": "object"
                        },
                        {
                          "properties": {
                            "maxChangesPerDay": {
                              "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                              "maximum": 100,
                              "minimum": 1,
                              "type": "integer"
                            },
                            "type": {
                              "description": "Pause the campaign, ad set or ad.",
                              "enum": [
                                "pause"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "type": "object"
                        },
                        {
                          "properties": {
                            "maxChangesPerDay": {
                              "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                              "maximum": 100,
                              "minimum": 1,
                              "type": "integer"
                            },
                            "type": {
                              "description": "Reactivate a campaign, ad set or ad a rule paused, once `cooldownMinutes` has passed since the pause. Objects you paused yourself are never touched.",
                              "enum": [
                                "activate"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "type": "object"
                        },
                        {
                          "properties": {
                            "direction": {
                              "enum": [
                                "increase",
                                "decrease"
                              ],
                              "type": "string"
                            },
                            "limit": {
                              "description": "The budget never goes above this on an increase, or below it on a decrease, in the ad account currency.",
                              "exclusiveMinimum": 0,
                              "type": "number"
                            },
                            "maxChangesPerDay": {
                              "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                              "maximum": 100,
                              "minimum": 1,
                              "type": "integer"
                            },
                            "percent": {
                              "description": "Change in percent: up to 100 for an increase, up to 90 for a decrease.",
                              "maximum": 100,
                              "minimum": 1,
                              "type": "integer"
                            },
                            "type": {
                              "description": "Change the daily budget. Not on ad-level rules (an ad has no budget), and on Google it needs a campaign-level rule (ad groups have no budget of their own).",
                              "enum": [
                                "adjust_budget"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "direction",
                            "limit",
                            "percent",
                            "type"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "adAccountId": {
                    "description": "Platform ad account ID, from `GET /apis/v1/ads/accounts`.",
                    "type": "string"
                  },
                  "campaignIds": {
                    "description": "Only check these platform campaign IDs (or their ad sets). Leave out to check the whole ad account. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "type": "array"
                  },
                  "conditions": {
                    "description": "Every condition must hold for an object to match. A rate with no denominator (a CPA with no conversions) never matches.",
                    "properties": {
                      "all": {
                        "items": {
                          "properties": {
                            "metric": {
                              "anyOf": [
                                {
                                  "enum": [
                                    "spend",
                                    "impressions",
                                    "clicks",
                                    "conversions",
                                    "ctr",
                                    "cpc",
                                    "cpm",
                                    "cpa",
                                    "roas",
                                    "reach",
                                    "frequency"
                                  ]
                                },
                                {
                                  "pattern": "^result:[a-z][a-z0-9_]{0,39}$"
                                }
                              ],
                              "description": "`ctr` is a percentage. `spend`, `cpc`, `cpm` and `cpa` are in the ad account currency. `reach` and `frequency` use the platform's de-duplicated reach, so they are accepted on Meta and TikTok only.",
                              "type": "string"
                            },
                            "op": {
                              "enum": [
                                ">",
                                ">=",
                                "<",
                                "<="
                              ],
                              "type": "string"
                            },
                            "value": {
                              "minimum": 0,
                              "type": "number"
                            },
                            "window": {
                              "description": "Days in the ad account's own timezone. `last_7d` is the 7 full days before today; only `today` reads the day in progress.",
                              "enum": [
                                "today",
                                "yesterday",
                                "last_3d",
                                "last_7d",
                                "last_14d",
                                "last_30d"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "metric",
                            "op",
                            "value",
                            "window"
                          ],
                          "type": "object"
                        },
                        "maxItems": 10,
                        "minItems": 1,
                        "type": "array"
                      }
                    },
                    "required": [
                      "all"
                    ],
                    "type": "object"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "cooldownMinutes": {
                    "default": 1440,
                    "description": "How long the rule leaves an object alone after acting on it.",
                    "maximum": 43200,
                    "minimum": 0,
                    "type": "integer"
                  },
                  "enabled": {
                    "default": true,
                    "type": "boolean"
                  },
                  "level": {
                    "description": "Whether the rule checks campaigns, ad sets or single ads. Each one is evaluated on its own.",
                    "enum": [
                      "campaign",
                      "adset",
                      "ad"
                    ],
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 200,
                    "minLength": 1,
                    "type": "string"
                  },
                  "schedule": {
                    "description": "Leave it out to run every 60 minutes.",
                    "properties": {
                      "everyMinutes": {
                        "description": "How often the rule runs, in minutes.",
                        "enum": [
                          60,
                          180,
                          360,
                          720,
                          1440
                        ],
                        "type": "integer"
                      }
                    },
                    "required": [
                      "everyMinutes"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "actions",
                  "adAccountId",
                  "conditions",
                  "level",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "rule": {
                      "properties": {
                        "actions": {
                          "description": "Each type at most once, and at most one of `pause`, `activate` and `adjust_budget`.",
                          "items": {
                            "oneOf": [
                              {
                                "properties": {
                                  "type": {
                                    "enum": [
                                      "notify"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "properties": {
                                  "maxChangesPerDay": {
                                    "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "type": {
                                    "description": "Pause the campaign, ad set or ad.",
                                    "enum": [
                                      "pause"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "properties": {
                                  "maxChangesPerDay": {
                                    "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "type": {
                                    "description": "Reactivate a campaign, ad set or ad a rule paused, once `cooldownMinutes` has passed since the pause. Objects you paused yourself are never touched.",
                                    "enum": [
                                      "activate"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "properties": {
                                  "direction": {
                                    "enum": [
                                      "increase",
                                      "decrease"
                                    ],
                                    "type": "string"
                                  },
                                  "limit": {
                                    "description": "The budget never goes above this on an increase, or below it on a decrease, in the ad account currency.",
                                    "exclusiveMinimum": 0,
                                    "type": "number"
                                  },
                                  "maxChangesPerDay": {
                                    "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "percent": {
                                    "description": "Change in percent: up to 100 for an increase, up to 90 for a decrease.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "type": {
                                    "description": "Change the daily budget. Not on ad-level rules (an ad has no budget), and on Google it needs a campaign-level rule (ad groups have no budget of their own).",
                                    "enum": [
                                      "adjust_budget"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "direction",
                                  "limit",
                                  "percent",
                                  "type"
                                ],
                                "type": "object"
                              }
                            ]
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "adAccountId": {
                          "description": "Platform ad account ID.",
                          "type": "string"
                        },
                        "campaignIds": {
                          "description": "Platform campaign IDs the rule is limited to. Null checks the whole ad account.",
                          "items": {
                            "type": "string"
                          },
                          "type": [
                            "array",
                            "null"
                          ]
                        },
                        "conditions": {
                          "description": "Every condition must hold for an object to match. A rate with no denominator (a CPA with no conversions) never matches.",
                          "properties": {
                            "all": {
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "maxItems": 10,
                              "minItems": 1,
                              "type": "array"
                            }
                          },
                          "required": [
                            "all"
                          ],
                          "type": "object"
                        },
                        "connectionId": {
                          "description": "The ads connection (adc_...) the object belongs to.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "cooldownMinutes": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "enabled": {
                          "type": "boolean"
                        },
                        "id": {
                          "type": "string"
                        },
                        "lastRunAt": {
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "level": {
                          "description": "Whether the rule checks campaigns, ad sets or single ads. Each one is evaluated on its own.",
                          "enum": [
                            "campaign",
                            "adset",
                            "ad"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "nextRunAt": {
                          "description": "Null while the rule is disabled.",
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platform": {
                          "description": "Ad platform, for example `facebook` (Meta) or `google`.",
                          "type": "string"
                        },
                        "schedule": {
                          "properties": {
                            "everyMinutes": {
                              "description": "How often the rule runs, in minutes.",
                              "enum": [
                                60,
                                180,
                                360,
                                720,
                                1440
                              ],
                              "type": "integer"
                            }
                          },
                          "required": [
                            "everyMinutes"
                          ],
                          "type": "object"
                        },
                        "updatedAt": {
                          "format": "date-time",
                          "type": "string"
                        }
                      },
                      "required": [
                        "actions",
                        "adAccountId",
                        "campaignIds",
                        "conditions",
                        "cooldownMinutes",
                        "createdAt",
                        "enabled",
                        "id",
                        "lastRunAt",
                        "level",
                        "name",
                        "nextRunAt",
                        "platform",
                        "schedule",
                        "updatedAt"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "rule"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Rule created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create an ad rule",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_ad_rule@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "7e7ddd48040ba204e9e4a0126d958da4eee34b2a8357f75d3fe5b5d1514a90de"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_rules",
          "method": "POST",
          "path": "/apis/v1/ads/rules"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_rules"
      }
    },
    "/apis/v1/ads/rules/activity": {
      "get": {
        "description": "Ad Rules. Read only. The permanent record of what your rules did: one entry per pause, reactivation or budget change (including skipped and failed attempts), newest first, across all rules of the profiles the key can reach. Entries stay after a rule is renamed or deleted; `ruleName` is the rule's name when it acted.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_rules_activity",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "ruleId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "enum": [
                "pause",
                "activate",
                "adjust_budget"
              ],
              "type": "string"
            }
          },
          {
            "description": "ISO 8601 date-time, inclusive.",
            "in": "query",
            "name": "from",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "ISO 8601 date-time, inclusive.",
            "in": "query",
            "name": "to",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "`nextCursor` from the previous page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "activity": {
                      "items": {
                        "properties": {
                          "adAccountId": {
                            "type": "string"
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "currency": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "description": "Stable ID of this entry.",
                            "type": "string"
                          },
                          "level": {
                            "enum": [
                              "campaign",
                              "adset"
                            ],
                            "type": "string"
                          },
                          "newDailyBudget": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "objectId": {
                            "description": "Platform ID of the campaign or ad set.",
                            "type": "string"
                          },
                          "objectName": {
                            "description": "Its name when the rule acted.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platform": {
                            "type": "string"
                          },
                          "previousDailyBudget": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "ranAt": {
                            "format": "date-time",
                            "type": "string"
                          },
                          "reason": {
                            "description": "Why it was skipped or failed, for example `already_paused`.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ruleId": {
                            "type": "string"
                          },
                          "ruleName": {
                            "description": "The rule's name when it acted.",
                            "type": "string"
                          },
                          "status": {
                            "enum": [
                              "done",
                              "skipped",
                              "failed"
                            ],
                            "type": "string"
                          },
                          "type": {
                            "enum": [
                              "pause",
                              "activate",
                              "adjust_budget"
                            ],
                            "type": "string"
                          }
                        },
                        "required": [
                          "adAccountId",
                          "currency",
                          "id",
                          "level",
                          "newDailyBudget",
                          "objectId",
                          "objectName",
                          "platform",
                          "previousDailyBudget",
                          "ranAt",
                          "reason",
                          "ruleId",
                          "ruleName",
                          "status",
                          "type"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "activity",
                    "nextCursor"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Changes, newest first"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List every change ad rules made",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_rule_activity@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "d0ca6f87e471ca67937f34c932a1ac81181772a9a33506c0ddcd4543a0c46d4a"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_rules_activity",
          "method": "GET",
          "path": "/apis/v1/ads/rules/activity"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_rules_activity"
      }
    },
    "/apis/v1/ads/rules/templates": {
      "get": {
        "description": "Ad Rules. Read only. Common rules to start from: stop losers, scale winners, pause ads with no conversions, creative fatigue and spend spike alerts. Each template is a complete rule body. Add `name`, `connectionId` and `adAccountId`, adjust the thresholds to the ad account, and send it to `POST /apis/v1/ads/rules`. Amounts are in the ad account currency.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_rules_templates",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "templates": {
                      "items": {
                        "properties": {
                          "actions": {
                            "description": "Each type at most once, and at most one of `pause`, `activate` and `adjust_budget`.",
                            "items": {
                              "oneOf": [
                                {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                {
                                  "additionalProperties": true,
                                  "type": "object"
                                }
                              ]
                            },
                            "minItems": 1,
                            "type": "array"
                          },
                          "conditions": {
                            "description": "Every condition must hold for an object to match. A rate with no denominator (a CPA with no conversions) never matches.",
                            "properties": {
                              "all": {
                                "items": {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                "maxItems": 10,
                                "minItems": 1,
                                "type": "array"
                              }
                            },
                            "required": [
                              "all"
                            ],
                            "type": "object"
                          },
                          "cooldownMinutes": {
                            "type": "integer"
                          },
                          "description": {
                            "type": "string"
                          },
                          "id": {
                            "type": "string"
                          },
                          "level": {
                            "description": "Whether the rule checks campaigns, ad sets or single ads. Each one is evaluated on its own.",
                            "enum": [
                              "campaign",
                              "adset",
                              "ad"
                            ],
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "platforms": {
                            "items": {
                              "type": "string"
                            },
                            "type": [
                              "array",
                              "null"
                            ]
                          },
                          "schedule": {
                            "properties": {
                              "everyMinutes": {
                                "description": "How often the rule runs, in minutes.",
                                "enum": [
                                  60,
                                  180,
                                  360,
                                  720,
                                  1440
                                ],
                                "type": "integer"
                              }
                            },
                            "required": [
                              "everyMinutes"
                            ],
                            "type": "object"
                          }
                        },
                        "required": [
                          "actions",
                          "conditions",
                          "cooldownMinutes",
                          "description",
                          "id",
                          "level",
                          "name",
                          "platforms",
                          "schedule"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "templates"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The templates."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List ready-made ad rules",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_rule_templates@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "23b95f8bbe9c4e3ca1fdb4921df206ae575c1294ae153a29dc4d345e8ac762ae"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_rules_templates",
          "method": "GET",
          "path": "/apis/v1/ads/rules/templates"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_rules_templates"
      }
    },
    "/apis/v1/ads/rules/{ruleId}": {
      "delete": {
        "description": "Ad Rules. Changes the ad account without starting or raising spend; audited. Deletes a rule and its run history. Changes the rule already made on the platform stay.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_rules_ruleid",
        "parameters": [
          {
            "in": "path",
            "name": "ruleId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Rule deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete an ad rule",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_rule@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "38655c5070b65f08e38913bafbc3bddffd45750f62514cb0eca62c3325b9b75b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_rules_ruleid",
          "method": "DELETE",
          "path": "/apis/v1/ads/rules/{ruleId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_rules_ruleid"
      },
      "get": {
        "description": "Ad Rules. Read only. Returns one ad rule.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_rules_ruleid",
        "parameters": [
          {
            "in": "path",
            "name": "ruleId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "rule": {
                      "properties": {
                        "actions": {
                          "description": "Each type at most once, and at most one of `pause`, `activate` and `adjust_budget`.",
                          "items": {
                            "oneOf": [
                              {
                                "properties": {
                                  "type": {
                                    "enum": [
                                      "notify"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "properties": {
                                  "maxChangesPerDay": {
                                    "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "type": {
                                    "description": "Pause the campaign, ad set or ad.",
                                    "enum": [
                                      "pause"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "properties": {
                                  "maxChangesPerDay": {
                                    "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "type": {
                                    "description": "Reactivate a campaign, ad set or ad a rule paused, once `cooldownMinutes` has passed since the pause. Objects you paused yourself are never touched.",
                                    "enum": [
                                      "activate"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "properties": {
                                  "direction": {
                                    "enum": [
                                      "increase",
                                      "decrease"
                                    ],
                                    "type": "string"
                                  },
                                  "limit": {
                                    "description": "The budget never goes above this on an increase, or below it on a decrease, in the ad account currency.",
                                    "exclusiveMinimum": 0,
                                    "type": "number"
                                  },
                                  "maxChangesPerDay": {
                                    "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "percent": {
                                    "description": "Change in percent: up to 100 for an increase, up to 90 for a decrease.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "type": {
                                    "description": "Change the daily budget. Not on ad-level rules (an ad has no budget), and on Google it needs a campaign-level rule (ad groups have no budget of their own).",
                                    "enum": [
                                      "adjust_budget"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "direction",
                                  "limit",
                                  "percent",
                                  "type"
                                ],
                                "type": "object"
                              }
                            ]
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "adAccountId": {
                          "description": "Platform ad account ID.",
                          "type": "string"
                        },
                        "campaignIds": {
                          "description": "Platform campaign IDs the rule is limited to. Null checks the whole ad account.",
                          "items": {
                            "type": "string"
                          },
                          "type": [
                            "array",
                            "null"
                          ]
                        },
                        "conditions": {
                          "description": "Every condition must hold for an object to match. A rate with no denominator (a CPA with no conversions) never matches.",
                          "properties": {
                            "all": {
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "maxItems": 10,
                              "minItems": 1,
                              "type": "array"
                            }
                          },
                          "required": [
                            "all"
                          ],
                          "type": "object"
                        },
                        "connectionId": {
                          "description": "The ads connection (adc_...) the object belongs to.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "cooldownMinutes": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "enabled": {
                          "type": "boolean"
                        },
                        "id": {
                          "type": "string"
                        },
                        "lastRunAt": {
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "level": {
                          "description": "Whether the rule checks campaigns, ad sets or single ads. Each one is evaluated on its own.",
                          "enum": [
                            "campaign",
                            "adset",
                            "ad"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "nextRunAt": {
                          "description": "Null while the rule is disabled.",
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platform": {
                          "description": "Ad platform, for example `facebook` (Meta) or `google`.",
                          "type": "string"
                        },
                        "schedule": {
                          "properties": {
                            "everyMinutes": {
                              "description": "How often the rule runs, in minutes.",
                              "enum": [
                                60,
                                180,
                                360,
                                720,
                                1440
                              ],
                              "type": "integer"
                            }
                          },
                          "required": [
                            "everyMinutes"
                          ],
                          "type": "object"
                        },
                        "updatedAt": {
                          "format": "date-time",
                          "type": "string"
                        }
                      },
                      "required": [
                        "actions",
                        "adAccountId",
                        "campaignIds",
                        "conditions",
                        "cooldownMinutes",
                        "createdAt",
                        "enabled",
                        "id",
                        "lastRunAt",
                        "level",
                        "name",
                        "nextRunAt",
                        "platform",
                        "schedule",
                        "updatedAt"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "rule"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Rule"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get an ad rule",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_rule@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0b237ba6efee028d92fcbf4e461026a7fb1180fec9f9f656ddfca757cf5abe48"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_rules_ruleid",
          "method": "GET",
          "path": "/apis/v1/ads/rules/{ruleId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_rules_ruleid"
      },
      "patch": {
        "description": "Ad Rules. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Changes an automated rule that can change budgets and turn delivery on or off. Changes any field of a rule except its connection and ad account. Send `campaignIds: null` to check the whole ad account again. Changing the schedule, or enabling a disabled rule, moves the next run; re-sending `enabled: true` on an enabled rule does not.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_rules_ruleid",
        "parameters": [
          {
            "in": "path",
            "name": "ruleId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "enabled": false,
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "actions": {
                    "description": "Each type at most once, and at most one of `pause`, `activate` and `adjust_budget`.",
                    "items": {
                      "oneOf": [
                        {
                          "properties": {
                            "type": {
                              "enum": [
                                "notify"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "type": "object"
                        },
                        {
                          "properties": {
                            "maxChangesPerDay": {
                              "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                              "maximum": 100,
                              "minimum": 1,
                              "type": "integer"
                            },
                            "type": {
                              "description": "Pause the campaign, ad set or ad.",
                              "enum": [
                                "pause"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "type": "object"
                        },
                        {
                          "properties": {
                            "maxChangesPerDay": {
                              "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                              "maximum": 100,
                              "minimum": 1,
                              "type": "integer"
                            },
                            "type": {
                              "description": "Reactivate a campaign, ad set or ad a rule paused, once `cooldownMinutes` has passed since the pause. Objects you paused yourself are never touched.",
                              "enum": [
                                "activate"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "type"
                          ],
                          "type": "object"
                        },
                        {
                          "properties": {
                            "direction": {
                              "enum": [
                                "increase",
                                "decrease"
                              ],
                              "type": "string"
                            },
                            "limit": {
                              "description": "The budget never goes above this on an increase, or below it on a decrease, in the ad account currency.",
                              "exclusiveMinimum": 0,
                              "type": "number"
                            },
                            "maxChangesPerDay": {
                              "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                              "maximum": 100,
                              "minimum": 1,
                              "type": "integer"
                            },
                            "percent": {
                              "description": "Change in percent: up to 100 for an increase, up to 90 for a decrease.",
                              "maximum": 100,
                              "minimum": 1,
                              "type": "integer"
                            },
                            "type": {
                              "description": "Change the daily budget. Not on ad-level rules (an ad has no budget), and on Google it needs a campaign-level rule (ad groups have no budget of their own).",
                              "enum": [
                                "adjust_budget"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "direction",
                            "limit",
                            "percent",
                            "type"
                          ],
                          "type": "object"
                        }
                      ]
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "campaignIds": {
                    "description": "Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 100,
                    "minItems": 1,
                    "type": [
                      "array",
                      "null"
                    ]
                  },
                  "conditions": {
                    "description": "Every condition must hold for an object to match. A rate with no denominator (a CPA with no conversions) never matches.",
                    "properties": {
                      "all": {
                        "items": {
                          "properties": {
                            "metric": {
                              "anyOf": [
                                {
                                  "enum": [
                                    "spend",
                                    "impressions",
                                    "clicks",
                                    "conversions",
                                    "ctr",
                                    "cpc",
                                    "cpm",
                                    "cpa",
                                    "roas",
                                    "reach",
                                    "frequency"
                                  ]
                                },
                                {
                                  "pattern": "^result:[a-z][a-z0-9_]{0,39}$"
                                }
                              ],
                              "description": "`ctr` is a percentage. `spend`, `cpc`, `cpm` and `cpa` are in the ad account currency. `reach` and `frequency` use the platform's de-duplicated reach, so they are accepted on Meta and TikTok only.",
                              "type": "string"
                            },
                            "op": {
                              "enum": [
                                ">",
                                ">=",
                                "<",
                                "<="
                              ],
                              "type": "string"
                            },
                            "value": {
                              "minimum": 0,
                              "type": "number"
                            },
                            "window": {
                              "description": "Days in the ad account's own timezone. `last_7d` is the 7 full days before today; only `today` reads the day in progress.",
                              "enum": [
                                "today",
                                "yesterday",
                                "last_3d",
                                "last_7d",
                                "last_14d",
                                "last_30d"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "metric",
                            "op",
                            "value",
                            "window"
                          ],
                          "type": "object"
                        },
                        "maxItems": 10,
                        "minItems": 1,
                        "type": "array"
                      }
                    },
                    "required": [
                      "all"
                    ],
                    "type": "object"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "cooldownMinutes": {
                    "maximum": 43200,
                    "minimum": 0,
                    "type": "integer"
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "level": {
                    "description": "Whether the rule checks campaigns, ad sets or single ads. Each one is evaluated on its own.",
                    "enum": [
                      "campaign",
                      "adset",
                      "ad"
                    ],
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 200,
                    "minLength": 1,
                    "type": "string"
                  },
                  "schedule": {
                    "properties": {
                      "everyMinutes": {
                        "description": "How often the rule runs, in minutes.",
                        "enum": [
                          60,
                          180,
                          360,
                          720,
                          1440
                        ],
                        "type": "integer"
                      }
                    },
                    "required": [
                      "everyMinutes"
                    ],
                    "type": "object"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "rule": {
                      "properties": {
                        "actions": {
                          "description": "Each type at most once, and at most one of `pause`, `activate` and `adjust_budget`.",
                          "items": {
                            "oneOf": [
                              {
                                "properties": {
                                  "type": {
                                    "enum": [
                                      "notify"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "properties": {
                                  "maxChangesPerDay": {
                                    "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "type": {
                                    "description": "Pause the campaign, ad set or ad.",
                                    "enum": [
                                      "pause"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "properties": {
                                  "maxChangesPerDay": {
                                    "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "type": {
                                    "description": "Reactivate a campaign, ad set or ad a rule paused, once `cooldownMinutes` has passed since the pause. Objects you paused yourself are never touched.",
                                    "enum": [
                                      "activate"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "type"
                                ],
                                "type": "object"
                              },
                              {
                                "properties": {
                                  "direction": {
                                    "enum": [
                                      "increase",
                                      "decrease"
                                    ],
                                    "type": "string"
                                  },
                                  "limit": {
                                    "description": "The budget never goes above this on an increase, or below it on a decrease, in the ad account currency.",
                                    "exclusiveMinimum": 0,
                                    "type": "number"
                                  },
                                  "maxChangesPerDay": {
                                    "description": "At most this many objects changed in any 24 hours, across runs. Matches over the limit are skipped with `daily_limit_reached` and tried again later.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "percent": {
                                    "description": "Change in percent: up to 100 for an increase, up to 90 for a decrease.",
                                    "maximum": 100,
                                    "minimum": 1,
                                    "type": "integer"
                                  },
                                  "type": {
                                    "description": "Change the daily budget. Not on ad-level rules (an ad has no budget), and on Google it needs a campaign-level rule (ad groups have no budget of their own).",
                                    "enum": [
                                      "adjust_budget"
                                    ],
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "direction",
                                  "limit",
                                  "percent",
                                  "type"
                                ],
                                "type": "object"
                              }
                            ]
                          },
                          "minItems": 1,
                          "type": "array"
                        },
                        "adAccountId": {
                          "description": "Platform ad account ID.",
                          "type": "string"
                        },
                        "campaignIds": {
                          "description": "Platform campaign IDs the rule is limited to. Null checks the whole ad account.",
                          "items": {
                            "type": "string"
                          },
                          "type": [
                            "array",
                            "null"
                          ]
                        },
                        "conditions": {
                          "description": "Every condition must hold for an object to match. A rate with no denominator (a CPA with no conversions) never matches.",
                          "properties": {
                            "all": {
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "maxItems": 10,
                              "minItems": 1,
                              "type": "array"
                            }
                          },
                          "required": [
                            "all"
                          ],
                          "type": "object"
                        },
                        "connectionId": {
                          "description": "The ads connection (adc_...) the object belongs to.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "cooldownMinutes": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "enabled": {
                          "type": "boolean"
                        },
                        "id": {
                          "type": "string"
                        },
                        "lastRunAt": {
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "level": {
                          "description": "Whether the rule checks campaigns, ad sets or single ads. Each one is evaluated on its own.",
                          "enum": [
                            "campaign",
                            "adset",
                            "ad"
                          ],
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "nextRunAt": {
                          "description": "Null while the rule is disabled.",
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platform": {
                          "description": "Ad platform, for example `facebook` (Meta) or `google`.",
                          "type": "string"
                        },
                        "schedule": {
                          "properties": {
                            "everyMinutes": {
                              "description": "How often the rule runs, in minutes.",
                              "enum": [
                                60,
                                180,
                                360,
                                720,
                                1440
                              ],
                              "type": "integer"
                            }
                          },
                          "required": [
                            "everyMinutes"
                          ],
                          "type": "object"
                        },
                        "updatedAt": {
                          "format": "date-time",
                          "type": "string"
                        }
                      },
                      "required": [
                        "actions",
                        "adAccountId",
                        "campaignIds",
                        "conditions",
                        "cooldownMinutes",
                        "createdAt",
                        "enabled",
                        "id",
                        "lastRunAt",
                        "level",
                        "name",
                        "nextRunAt",
                        "platform",
                        "schedule",
                        "updatedAt"
                      ],
                      "type": "object"
                    }
                  },
                  "required": [
                    "rule"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Rule updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update an ad rule",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_rule@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1dc1fc94298fa8ea739f50b98dbb43e726ad07eec8f028493d7655b8ef213047"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_rules_ruleid",
          "method": "PATCH",
          "path": "/apis/v1/ads/rules/{ruleId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_rules_ruleid"
      }
    },
    "/apis/v1/ads/rules/{ruleId}/preview": {
      "post": {
        "description": "Ad Rules. Read only. Works on disabled rules.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_rules_ruleid_preview",
        "parameters": [
          {
            "in": "path",
            "name": "ruleId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "currency": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "evaluatedAt": {
                      "format": "date-time",
                      "type": "string"
                    },
                    "matched": {
                      "description": "How many objects meet every condition.",
                      "type": "integer"
                    },
                    "objects": {
                      "description": "Every delivering campaign or ad set in scope (for an `activate` rule, the rule-paused ones it may reactivate).",
                      "items": {
                        "properties": {
                          "campaignId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "conditions": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "id": {
                            "description": "Platform ID of the campaign or ad set.",
                            "type": "string"
                          },
                          "matched": {
                            "description": "True when every condition holds.",
                            "type": "boolean"
                          },
                          "name": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "campaignId",
                          "conditions",
                          "id",
                          "matched",
                          "name"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "timezone": {
                      "description": "IANA timezone of the ad account.",
                      "type": "string"
                    },
                    "timezoneAssumed": {
                      "description": "True when the ad account has no known timezone and UTC was assumed.",
                      "type": "boolean"
                    },
                    "today": {
                      "description": "The ad account's calendar date the windows were resolved against.",
                      "format": "date",
                      "type": "string"
                    }
                  },
                  "required": [
                    "currency",
                    "evaluatedAt",
                    "matched",
                    "objects",
                    "timezone",
                    "timezoneAssumed",
                    "today"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Evaluation"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Preview an ad rule",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.preview_ad_rule@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a11c84e28eeeea61f30481f4d8ef2caef6ed57d5b74ed23c3f8aff8d849941c5"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_rules_ruleid_preview",
          "method": "POST",
          "path": "/apis/v1/ads/rules/{ruleId}/preview"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_rules_ruleid_preview"
      }
    },
    "/apis/v1/ads/rules/{ruleId}/runs": {
      "get": {
        "description": "Ad Rules. Read only. Lists a rule's scheduled runs, newest first: what each run evaluated, matched and did. Runs that changed something (or tried to) are kept permanently, also after the rule is deleted; runs that changed nothing are dropped after about 31 days. For every change across all rules, use `GET /apis/v1/ads/rules/activity`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_rules_ruleid_runs",
        "parameters": [
          {
            "in": "path",
            "name": "ruleId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "skip",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "runs": {
                      "items": {
                        "properties": {
                          "actedObjectIds": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "error": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "evaluation": {
                            "description": "The matched objects with their condition values, and what each action did.",
                            "properties": {
                              "actions": {
                                "items": {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "currency": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "matched": {
                                "items": {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "notification": {
                                "additionalProperties": true,
                                "description": "`failed`: it could not be queued.",
                                "type": "object"
                              },
                              "rule": {
                                "additionalProperties": true,
                                "description": "The rule as it was when this run happened, so its actions stay readable after the rule is renamed or deleted. Absent on runs recorded before October 2026.",
                                "type": "object"
                              },
                              "timezone": {
                                "type": "string"
                              },
                              "timezoneAssumed": {
                                "type": "boolean"
                              },
                              "today": {
                                "format": "date",
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "id": {
                            "type": "string"
                          },
                          "objectsEvaluated": {
                            "type": "integer"
                          },
                          "outcome": {
                            "description": "Result of the rule run: `cooldown`: objects matched but all were in cooldown. `no_match`: nothing matched.",
                            "enum": [
                              "triggered",
                              "cooldown",
                              "no_match",
                              "failed"
                            ],
                            "type": "string"
                          },
                          "ranAt": {
                            "format": "date-time",
                            "type": "string"
                          }
                        },
                        "required": [
                          "actedObjectIds",
                          "error",
                          "evaluation",
                          "id",
                          "objectsEvaluated",
                          "outcome",
                          "ranAt"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "runs"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Runs"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List an ad rule's runs",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_rule_runs@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "4b927e5c7d108e8b57604de3bfe148e084ec12e25359027396fdaf1478344924"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_rules_ruleid_runs",
          "method": "GET",
          "path": "/apis/v1/ads/rules/{ruleId}/runs"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_rules_ruleid_runs"
      }
    },
    "/apis/v1/ads/search-terms": {
      "get": {
        "description": "Ad Insights. Read only. Shows the actual Google searches that triggered your ads, with spend and results, so you can spot wasted spend and add negative keywords. Each row is a search query with its matched-keyword status and spend metrics: the raw material for wasted-spend analysis and negative-keyword lists. Reads Google's `search_term_view`, cached for the quota window. Defaults to the last 30 days.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_search_terms",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Defaults to the account's connected customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adAccountId, kept for existing callers",
            "in": "query",
            "name": "customerId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Defaults to 30 days ago.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Defaults to today.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Numeric Google campaign id filter. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Platform ad set ID (Google ad group). Same value as adSetId on listAdKeywords and /ad-sets/{adSetId}/assets. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "adSetId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Alias of adSetId, kept for existing callers. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "adGroupId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Cursor from paging.nextPageToken of the previous page.",
            "in": "query",
            "name": "pageToken",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "cachedAt": {
                      "description": "When this data was fetched from Google. Null when it was never served from cache.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "customerId": {
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "properties": {
                          "adGroupId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "adGroupName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "clicks": {
                            "type": "integer"
                          },
                          "conversions": {
                            "type": "number"
                          },
                          "conversionsValue": {
                            "type": "number"
                          },
                          "costMicros": {
                            "description": "Cost in micros of the account currency (divide by 1,000,000).",
                            "type": "integer"
                          },
                          "impressions": {
                            "type": "integer"
                          },
                          "matchSource": {
                            "description": "What matched the term: ADVERTISER_PROVIDED_KEYWORD (one of your keywords), AI_MAX_BROAD_MATCH or AI_MAX_KEYWORDLESS (AI Max expansion).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "matchType": {
                            "description": "How the term matched (BROAD, PHRASE, EXACT, NEAR_PHRASE, NEAR_EXACT).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "searchTerm": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "description": "ADDED / EXCLUDED / ADDED_EXCLUDED / NONE: whether the term is already a keyword or a negative.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "nextPageToken": {
                          "description": "Null when the last page was returned.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    },
                    "stale": {
                      "description": "True when Google's daily API quota was exhausted and this is the last successful fetch, not a live read.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Search terms"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Google Ads search terms report",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ads_search_terms@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "2cde4a7429436e0d24cb995d712b9f91282204a6f4355b391a396a34d5f69e59"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_search_terms",
          "method": "GET",
          "path": "/apis/v1/ads/search-terms"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_search_terms"
      }
    },
    "/apis/v1/ads/shared-budgets": {
      "get": {
        "description": "Ad Campaigns. Read only. Lists a Google Ads account's shared budgets and how many campaigns draw from each. Lists the Google Ads customer's shared campaign budgets (`campaign_budget.explicitly_shared` = true, not removed), with how many campaigns use each. Move a campaign onto one with `sharedBudgetId` on PUT /apis/v1/ads/campaigns/{campaignId}. Google only; other platforms return 501.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_shared_budgets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Platform ad account ID (Google customer ID, digits only). Defaults to the account's connected customer.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "budgets": {
                      "items": {
                        "properties": {
                          "amount": {
                            "description": "In the account's currency units.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "campaignCount": {
                            "description": "campaign_budget.reference_count",
                            "type": "integer"
                          },
                          "deliveryMethod": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "id": {
                            "description": "Numeric budget id; pass as sharedBudgetId.",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "type": {
                            "enum": [
                              "daily",
                              "lifetime",
                              null
                            ],
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "customerId": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Shared budgets"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List shared budgets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_shared_budgets@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "315d4cb7fd9ee45df2ee80e6ff22198a84946a4953d4b22e67a01cb0545d5025"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_shared_budgets",
          "method": "GET",
          "path": "/apis/v1/ads/shared-budgets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_shared_budgets"
      },
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Creates a budget campaigns can share and spend. Creates a daily Google Ads budget that several campaigns can share. Creates a daily shared campaign budget (`explicitly_shared: true`, standard delivery) that several campaigns can draw from. A lifetime budget returns 422, like every Google budget. Google refuses some bidding strategies on a shared budget; that error surfaces when a campaign is moved onto it.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_shared_budgets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "amount": 10,
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account ID (Google customer ID, digits only). Defaults to the account's connected customer.",
                    "type": "string"
                  },
                  "amount": {
                    "description": "Daily amount in the account's currency units.",
                    "exclusiveMinimum": 0,
                    "type": "number"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "type": {
                    "default": "daily",
                    "description": "Only daily is accepted (lifetime returns 422).",
                    "enum": [
                      "daily",
                      "lifetime"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "amount",
                  "name"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "budget": {
                      "properties": {
                        "customerId": {
                          "type": "string"
                        },
                        "id": {
                          "type": "string"
                        },
                        "resourceName": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Shared budget created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a shared budget",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_shared_budget@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "a3c2f080450536d1d75d2725dfd0a94ec05cd4e4c6e2f86240c192d600f64c62"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_shared_budgets",
          "method": "POST",
          "path": "/apis/v1/ads/shared-budgets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_shared_budgets"
      }
    },
    "/apis/v1/ads/studies": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the A/B tests and lift studies on a Meta ad account, with their timing and test groups. Lists the ad account's A/B tests and lift studies (Meta's `/act_X/ad_studies`), rows returned verbatim. The default projection covers id, name, type, timing and cells with split percentages; `fields` is a raw-passthrough override.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_studies",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Graph field override.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Rows per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "description": "Raw Meta ad study row.",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad studies (raw Meta shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "A/B tests and lift studies",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_studies@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "28733638598bd74dd0b33ddc3d23426409a442eee8b6e473607d0c3304d1273e"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_studies",
          "method": "GET",
          "path": "/apis/v1/ads/studies"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_studies"
      }
    },
    "/apis/v1/ads/targeting/bid-pricing": {
      "post": {
        "description": "Ad Targeting. Read only. LinkedIn-only. Returns the suggested bid and bid limits for a targeting spec, plus the daily-budget bounds LinkedIn will accept. Use it before creating a campaign to pick a bid inside the allowed range and warn the user if their daily budget is below the minimum. Wraps LinkedIn's `adBudgetPricing` finder.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_targeting_bid_pricing",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "spec": {
                  "ageMax": 13,
                  "ageMin": 13
                }
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "LinkedIn ad account ID (numeric).",
                    "type": "string"
                  },
                  "bidType": {
                    "description": "Defaults to CPM.",
                    "enum": [
                      "CPM",
                      "CPC",
                      "CPV"
                    ],
                    "type": "string"
                  },
                  "campaignType": {
                    "description": "Defaults to SPONSORED_UPDATES.",
                    "enum": [
                      "TEXT_AD",
                      "SPONSORED_UPDATES",
                      "SPONSORED_INMAILS"
                    ],
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "currency": {
                    "description": "ISO 4217, defaults to USD.",
                    "maxLength": 3,
                    "minLength": 3,
                    "type": "string"
                  },
                  "dailyBudget": {
                    "description": "Optional daily budget in whole account-currency units. LinkedIn refines the suggested bid to this budget.",
                    "type": "number"
                  },
                  "matchType": {
                    "description": "Defaults to EXACT.",
                    "enum": [
                      "EXACT",
                      "AUDIENCE_EXPANDED"
                    ],
                    "type": "string"
                  },
                  "objectiveType": {
                    "description": "LinkedIn objectiveType, e.g. WEBSITE_VISIT, LEAD_GENERATION, VIDEO_VIEW.",
                    "type": "string"
                  },
                  "optimizationTargetType": {
                    "description": "LinkedIn optimizationTargetType, e.g. MAX_CLICK, MAX_IMPRESSION.",
                    "type": "string"
                  },
                  "spec": {
                    "description": "Same targeting spec used by POST /apis/v1/ads/create.",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  }
                },
                "required": [
                  "adAccountId",
                  "spec"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "available": {
                      "type": "boolean"
                    },
                    "pricing": {
                      "description": "LinkedIn's adBudgetPricing element. Null when LinkedIn has no data for the combination.",
                      "properties": {
                        "bidLimits": {
                          "properties": {
                            "max": {
                              "properties": {
                                "amount": {
                                  "description": "Amount as a decimal string, e.g. \"88.59\".",
                                  "type": "string"
                                },
                                "currencyCode": {
                                  "description": "ISO 4217 currency code, e.g. \"USD\".",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "currencyCode"
                              ],
                              "type": "object"
                            },
                            "min": {
                              "properties": {
                                "amount": {
                                  "description": "Amount as a decimal string, e.g. \"88.59\".",
                                  "type": "string"
                                },
                                "currencyCode": {
                                  "description": "ISO 4217 currency code, e.g. \"USD\".",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "currencyCode"
                              ],
                              "type": "object"
                            }
                          },
                          "type": "object"
                        },
                        "dailyBudgetLimits": {
                          "properties": {
                            "default": {
                              "properties": {
                                "amount": {
                                  "description": "Amount as a decimal string, e.g. \"88.59\".",
                                  "type": "string"
                                },
                                "currencyCode": {
                                  "description": "ISO 4217 currency code, e.g. \"USD\".",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "currencyCode"
                              ],
                              "type": "object"
                            },
                            "max": {
                              "properties": {
                                "amount": {
                                  "description": "Amount as a decimal string, e.g. \"88.59\".",
                                  "type": "string"
                                },
                                "currencyCode": {
                                  "description": "ISO 4217 currency code, e.g. \"USD\".",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "currencyCode"
                              ],
                              "type": "object"
                            },
                            "min": {
                              "properties": {
                                "amount": {
                                  "description": "Amount as a decimal string, e.g. \"88.59\".",
                                  "type": "string"
                                },
                                "currencyCode": {
                                  "description": "ISO 4217 currency code, e.g. \"USD\".",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "currencyCode"
                              ],
                              "type": "object"
                            }
                          },
                          "type": "object"
                        },
                        "suggestedBid": {
                          "properties": {
                            "default": {
                              "properties": {
                                "amount": {
                                  "description": "Amount as a decimal string, e.g. \"88.59\".",
                                  "type": "string"
                                },
                                "currencyCode": {
                                  "description": "ISO 4217 currency code, e.g. \"USD\".",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "currencyCode"
                              ],
                              "type": "object"
                            },
                            "max": {
                              "properties": {
                                "amount": {
                                  "description": "Amount as a decimal string, e.g. \"88.59\".",
                                  "type": "string"
                                },
                                "currencyCode": {
                                  "description": "ISO 4217 currency code, e.g. \"USD\".",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "currencyCode"
                              ],
                              "type": "object"
                            },
                            "min": {
                              "properties": {
                                "amount": {
                                  "description": "Amount as a decimal string, e.g. \"88.59\".",
                                  "type": "string"
                                },
                                "currencyCode": {
                                  "description": "ISO 4217 currency code, e.g. \"USD\".",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "amount",
                                "currencyCode"
                              ],
                              "type": "object"
                            }
                          },
                          "type": "object"
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "available"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Pricing insights"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Suggested bid and budget bounds",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_linked_in_bid_pricing@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "425dcdced3117a658a55a23365185cf4cf6816bf2456a54b6e10a5469d710824"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_targeting_bid_pricing",
          "method": "POST",
          "path": "/apis/v1/ads/targeting/bid-pricing"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_targeting_bid_pricing"
      }
    },
    "/apis/v1/ads/targeting/browse": {
      "get": {
        "description": "Ad Targeting. Read only. Shows Meta's full tree of detailed targeting categories for an ad account, so you can browse options without a keyword. It returns the whole Meta detailed-targeting category tree of one ad account (Meta's `GET /act_{ad_account_id}/targetingbrowse`), as one flat list you can render as a tree.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_targeting_browse",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "The Meta ad account to browse as, in the form \"act_\".",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "pattern": "^act_\\d+$",
              "type": "string"
            }
          },
          {
            "description": "Only the nodes of this Meta type (e.g. interests, behaviors, life_events, income), plus the organizational nodes leading to them. A type that is not in the catalog returns 400.",
            "in": "query",
            "name": "type",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only the descendants (every depth) of this organizational node, e.g. `Demographics > Financial`. A nodeId that is not an organizational node of the catalog returns 400.",
            "in": "query",
            "name": "parentNodeId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "`true` for selectable entities only, `false` for organizational nodes only.",
            "in": "query",
            "name": "selectable",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "nodes": {
                      "items": {
                        "properties": {
                          "audienceSizeLowerBound": {
                            "description": "Meta's estimated audience size, lower bound, when reported.",
                            "type": "integer"
                          },
                          "audienceSizeUpperBound": {
                            "description": "Meta's estimated audience size, upper bound, when reported.",
                            "type": "integer"
                          },
                          "description": {
                            "description": "Meta's description, when it has one.",
                            "type": "string"
                          },
                          "id": {
                            "description": "Meta targeting id, null on organizational nodes.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "nodeId": {
                            "description": "Identifies the node within this response. Not a Meta id: never put it in a targeting spec.",
                            "type": "string"
                          },
                          "parentNodeId": {
                            "description": "nodeId of the parent organizational node, null for a root.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "path": {
                            "description": "Labels of the ancestors, root first. Does not include the node itself.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "selectable": {
                            "description": "True when the node can be targeted (it has a Meta id).",
                            "type": "boolean"
                          },
                          "type": {
                            "description": "Meta's targeting spec key (interests, behaviors, industries, life_events, education_statuses, relationship_statuses, family_statuses, income, ...). Null on most organizational nodes.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "nodeId",
                          "parentNodeId",
                          "path",
                          "selectable",
                          "type"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "adAccountId",
                    "nodes"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "The category tree as a flat list, in Meta's order (parents before their children)."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Browse targeting categories",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.browse_ad_targeting@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "f4fa4f70e0ac9ae5cf069a79241037be477e7c94e5741e635fc2252782841f77"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_targeting_browse",
          "method": "GET",
          "path": "/apis/v1/ads/targeting/browse"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_targeting_browse"
      }
    },
    "/apis/v1/ads/targeting/reach-estimate": {
      "post": {
        "description": "Ad Targeting. Read only. Estimates how many people a targeting setup would reach before you create a campaign. Returns a normalized pre-flight audience-size estimate for a targeting spec, before any campaign is created. Backed by each platform's native reach API (Meta `delivery_estimate`, LinkedIn `audienceCounts`, X `audience_summary`, Pinterest `audience_sizing`).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_targeting_reach_estimate",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Required. The platform ad-account ID the reach call runs against (Meta act_..., LinkedIn numeric sponsoredAccount ID, Pinterest ad-account ID, X account ID) - every backing reach API is scoped to one ad account.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "optimizationGoal": {
                    "description": "Optional. The optimization goal the estimate should assume (platform's own vocabulary, e.g. Meta `REACH`, `LINK_CLICKS`, `OFFSITE_CONVERSIONS`). Some platforms vary the estimate by goal; omit to use the platform default.",
                    "type": "string"
                  },
                  "rawTargeting": {
                    "additionalProperties": true,
                    "description": "Meta only.",
                    "type": "object"
                  },
                  "spec": {
                    "description": "The targeting spec to estimate. Same shape used by POST /apis/v1/ads/create. Required unless `rawTargeting` is sent; with `rawTargeting` it can be omitted or minimal.",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  }
                },
                "required": [
                  "adAccountId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "active": {
                      "description": "LinkedIn only. LinkedIn's `audienceCounts.active`, verbatim: the active subset of the same audience `lower`/`upper` carry as its `total`. Absent when LinkedIn does not report it; `0` is a real answer, not a missing one.",
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "available": {
                      "description": "Whether a pre-flight estimate is available on this platform. False for Google and TikTok.",
                      "type": "boolean"
                    },
                    "currency": {
                      "description": "Currency of any monetary fields in the estimate, when applicable.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "daily": {
                      "description": "Optional estimated daily reach/results at the given budget, when the platform returns it.",
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "estimateReady": {
                      "description": "Meta only. False when Meta is still computing the estimate (the audience is too new); retry shortly.",
                      "type": [
                        "boolean",
                        "null"
                      ]
                    },
                    "lower": {
                      "description": "Lower bound of the estimated reachable audience. Present only when available.",
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "upper": {
                      "description": "Upper bound of the estimated reachable audience. Present only when available.",
                      "type": [
                        "integer",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "available"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Normalized reach estimate"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Estimate audience reach",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.estimate_ad_reach@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "aa7a240b33bf43608965298abad746e74cbb17355d9ff1dab29dd29a736c2b7f"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_targeting_reach_estimate",
          "method": "POST",
          "path": "/apis/v1/ads/targeting/reach-estimate"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_targeting_reach_estimate"
      }
    },
    "/apis/v1/ads/targeting/search": {
      "get": {
        "description": "Ad Targeting. Read only. Finds targeting options by name, such as locations, interests or behaviors, and returns the ids to use in ad targeting. It resolves a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec`: the `countries`/`regions`/`cities`/`zips`/`metros` geo keys and the `interests`/`behaviors` entity ids.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_targeting_search",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Search query. For geo, the locality name only (no region/country suffix). For `interestSuggestion`, the interest names: comma-separated, or a JSON array of strings when a name contains a comma (a `q` starting with `[` is read as JSON).",
            "in": "query",
            "name": "q",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "What to search. Defaults to `interest` for backward compatibility with the deprecated /apis/v1/ads/interests alias. `geo`: resolves locations (scope further with `geoType`).",
            "in": "query",
            "name": "dimension",
            "required": false,
            "schema": {
              "default": "interest",
              "enum": [
                "geo",
                "interest",
                "interestSuggestion",
                "interestKeyword",
                "behavior",
                "hashtag",
                "income",
                "language",
                "workPosition",
                "workEmployer",
                "workIndustry",
                "industry",
                "jobFunction",
                "seniority",
                "companySize",
                "skill",
                "community",
                "conversationKeyword"
              ],
              "type": "string"
            }
          },
          {
            "description": "Only used when `dimension=geo`. The kind of location to resolve. `all` searches every type in one relevance-ranked call. Defaults to `city`.",
            "in": "query",
            "name": "geoType",
            "required": false,
            "schema": {
              "default": "city",
              "enum": [
                "all",
                "country",
                "country_group",
                "region",
                "city",
                "subcity",
                "neighborhood",
                "place",
                "zip",
                "metro_area",
                "geo_market"
              ],
              "type": "string"
            }
          },
          {
            "description": "ISO 3166-1 alpha-2 country code (e.g. NL) to scope a geo search.",
            "in": "query",
            "name": "countryCode",
            "required": false,
            "schema": {
              "maxLength": 2,
              "minLength": 2,
              "type": "string"
            }
          },
          {
            "description": "TikTok only: the advertiser to search as, when the connection holds several. Each TikTok advertiser has its own targetable regions and catalogs.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only (ignored on other platforms). The language Meta matches `q` against and names results and `path` in, as language_TERRITORY (e.g. `pl_PL`, `en_US`).",
            "in": "query",
            "name": "locale",
            "required": false,
            "schema": {
              "pattern": "^[a-z]{2,3}_[A-Z]{2}$",
              "type": "string"
            }
          },
          {
            "description": "Maximum results to return.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "results": {
                      "items": {
                        "properties": {
                          "audienceSize": {
                            "description": "Optional estimated reachable users for this option, when the platform returns it.",
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "countryCode": {
                            "description": "ISO-3166 alpha-2 of the country a sub-country geo result (city, region, zip, metro) belongs to, when the platform reports it (Meta does). Useful to know whether a location falls under the EU DSA disclosure rules before creating the ad.",
                            "type": "string"
                          },
                          "id": {
                            "description": "The platform's opaque id. Use as a geo `key` (regions/cities/zips/metros) or an entity `id` (interests/behaviors) in TargetingSpec.",
                            "type": "string"
                          },
                          "name": {
                            "description": "Human-readable label.",
                            "type": "string"
                          },
                          "path": {
                            "description": "Optional breadcrumb of parent labels (e.g. ['United States', 'California', 'Los Angeles']). Disambiguates same-named results.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "platformId": {
                            "description": "The platform's own id for the result. Reddit `community` results: Reddit's own subreddit id (the `id` is the name). `country` results: the platform's own id for the country, which `id` replaced with the ISO code.",
                            "type": "string"
                          },
                          "status": {
                            "description": "TikTok `interestKeyword` and `hashtag` results only: TikTok's availability status. `EFFECTIVE` / `INEFFECTIVE` for additional interests, `ONLINE` / `OFFLINE` for hashtags. Only `EFFECTIVE` and `ONLINE` ids can be targeted.",
                            "type": "string"
                          },
                          "type": {
                            "description": "What the result is.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "type"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Matching targeting options (normalized)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Search targeting options",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.search_ad_targeting@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "7798396493a9c77c90264ef4c12850908093d95a8ac1e73d51644f8ea0eebfa8"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_targeting_search",
          "method": "GET",
          "path": "/apis/v1/ads/targeting/search"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_targeting_search"
      }
    },
    "/apis/v1/ads/targeting/supply-forecast": {
      "post": {
        "description": "Ad Targeting. Read only. LinkedIn-only. Forecasted impressions, clicks, spend and ~20 other metrics for a targeting spec over a time range. Wraps LinkedIn's `adSupplyForecasts` finder. Each returned series carries a `metricType` (IMPRESSION, CLICK, SPENDING, MAX_POTENTIAL_BUDGET, COST_PER_MILLION_IMPRESSIONS, ...) and a `granularity` (DAILY, SEVEN_DAY, THIRTY_DAY, CUSTOM).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_targeting_supply_forecast",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "spec": {
                  "ageMax": 13,
                  "ageMin": 13
                },
                "timeRangeEnd": 10,
                "timeRangeStart": 10
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "type": "string"
                  },
                  "campaignType": {
                    "description": "Defaults to SPONSORED_UPDATES.",
                    "enum": [
                      "SPONSORED_UPDATES",
                      "SPONSORED_INMAILS",
                      "DYNAMIC"
                    ],
                    "type": "string"
                  },
                  "competingBid": {
                    "description": "Required for manual-bid forecasts (when optimizationTarget is not set).",
                    "properties": {
                      "amount": {
                        "type": "number"
                      },
                      "bidType": {
                        "enum": [
                          "CPM",
                          "CPC",
                          "CPV"
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "amount",
                      "bidType"
                    ],
                    "type": "object"
                  },
                  "connectedTelevisionOnly": {
                    "description": "Defaults to false.",
                    "type": "boolean"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "currency": {
                    "description": "ISO 4217, defaults to USD.",
                    "maxLength": 3,
                    "minLength": 3,
                    "type": "string"
                  },
                  "dailyBudget": {
                    "description": "Either dailyBudget or totalBudget is required.",
                    "type": "number"
                  },
                  "enableAudienceExpansion": {
                    "description": "Defaults to false.",
                    "type": "boolean"
                  },
                  "enableAudienceNetwork": {
                    "description": "Defaults to false. Required true for connectedTelevisionOnly.",
                    "type": "boolean"
                  },
                  "objectiveType": {
                    "type": "string"
                  },
                  "optimizationTarget": {
                    "description": "When set, the forecast assumes auto-bidding. When unset, competingBid is required.",
                    "type": "string"
                  },
                  "spec": {
                    "description": "Normalized, platform-agnostic ad-targeting spec. Every field is optional; an empty object targets the platform's default broadest audience.",
                    "properties": {
                      "ageMax": {
                        "description": "Maximum age. Same per-platform application and clamping as ageMin.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "description": "Minimum age. Applied on Meta, TikTok, Pinterest, LinkedIn, X and Google Search/Display (Google excludes the age ranges outside the request). Rejected with 400 on OpenAI, Reddit and Google Performance Max / Demand Gen.",
                        "maximum": 100,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "audienceExclude": {
                        "description": "Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "audienceInclude": {
                        "description": "Platform audience IDs to include, as returned by GET /apis/v1/ads/audiences: Meta: custom audience ids. TikTok: audience ids. Pinterest: customer list ids. LinkedIn: segment ids (the platformAudienceId from GET /apis/v1/ads/audiences). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "behaviors": {
                        "description": "Behaviour entities from /apis/v1/ads/targeting/search?dimension=behavior (Meta, TikTok and LinkedIn). On TikTok they target people who, in the picked categories:",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "cities": {
                        "description": "City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "communities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to target, by name, with or without the `r/` prefix (e.g. `['marketing', 'r/startups']`), as returned by /apis/v1/ads/targeting/search?dimension=community.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "companySizes": {
                        "description": "LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /apis/v1/ads/targeting/search?dimension=companySize.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "conversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Keywords that place the ad in Reddit conversations about them, as returned by /apis/v1/ads/targeting/search?dimension=conversationKeyword.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 country codes (e.g. ['US']).",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "countryGroups": {
                        "description": "Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`.",
                        "items": {
                          "enum": [
                            "africa",
                            "asia",
                            "europe",
                            "north_america",
                            "south_america",
                            "oceania",
                            "central_america",
                            "caribbean",
                            "eea",
                            "euro_area",
                            "nafta",
                            "mercosur",
                            "afta",
                            "apec",
                            "gcc",
                            "cisfta",
                            "emerging_markets",
                            "itunes_app_store",
                            "android_free_store",
                            "android_paid_store"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "customLocations": {
                        "description": "Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.",
                        "items": {
                          "properties": {
                            "address": {
                              "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                              "type": "string"
                            },
                            "distanceUnit": {
                              "enum": [
                                "mile",
                                "kilometer"
                              ],
                              "type": "string"
                            },
                            "latitude": {
                              "maximum": 90,
                              "minimum": -90,
                              "type": "number"
                            },
                            "longitude": {
                              "maximum": 180,
                              "minimum": -180,
                              "type": "number"
                            },
                            "name": {
                              "type": "string"
                            },
                            "radius": {
                              "description": "Positive radius around the point.",
                              "type": "number"
                            }
                          },
                          "required": [
                            "distanceUnit",
                            "latitude",
                            "longitude",
                            "radius"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "excludedCommunities": {
                        "description": "Reddit only (400 elsewhere). Subreddits to exclude, named like `communities`.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedConversationKeywords": {
                        "description": "Reddit only (400 elsewhere). Conversation keywords to keep the ad away from.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "excludedLocations": {
                        "description": "Geo to exclude from the audience. Mirrors the inclusion geo shape. Meta (excluded_geo_locations): excluded cities can carry a radius catchment, and excluded custom (lat/lng) pins are supported.",
                        "properties": {
                          "cities": {
                            "description": "Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.",
                            "items": {
                              "properties": {
                                "distanceUnit": {
                                  "description": "Required if radius is set.",
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "key": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Radius around the excluded city. Requires distanceUnit.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "countries": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "countryGroups": {
                            "description": "Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).",
                            "items": {
                              "enum": [
                                "africa",
                                "asia",
                                "europe",
                                "north_america",
                                "south_america",
                                "oceania",
                                "central_america",
                                "caribbean",
                                "eea",
                                "euro_area",
                                "nafta",
                                "mercosur",
                                "afta",
                                "apec",
                                "gcc",
                                "cisfta",
                                "emerging_markets",
                                "itunes_app_store",
                                "android_free_store",
                                "android_paid_store"
                              ],
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "customLocations": {
                            "description": "Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.",
                            "items": {
                              "properties": {
                                "address": {
                                  "description": "Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.",
                                  "type": "string"
                                },
                                "distanceUnit": {
                                  "enum": [
                                    "mile",
                                    "kilometer"
                                  ],
                                  "type": "string"
                                },
                                "latitude": {
                                  "maximum": 90,
                                  "minimum": -90,
                                  "type": "number"
                                },
                                "longitude": {
                                  "maximum": 180,
                                  "minimum": -180,
                                  "type": "number"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "radius": {
                                  "description": "Positive radius around the point.",
                                  "type": "number"
                                }
                              },
                              "required": [
                                "distanceUnit",
                                "latitude",
                                "longitude",
                                "radius"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "neighborhoods": {
                            "description": "Named neighbourhood areas to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "places": {
                            "description": "Named points of interest to exclude. `key` from /apis/v1/ads/targeting/search.",
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "regions": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "zips": {
                            "items": {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "gender": {
                        "description": "Restrict by gender. 'all' (default) targets everyone.",
                        "enum": [
                          "all",
                          "male",
                          "female"
                        ],
                        "type": "string"
                      },
                      "incomeTier": {
                        "description": "Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected.",
                        "enum": [
                          "top_5",
                          "top_10",
                          "top_10_25",
                          "top_25_50"
                        ],
                        "type": "string"
                      },
                      "industries": {
                        "description": "LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /apis/v1/ads/targeting/search?dimension=industry.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest entities from /apis/v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "jobFunctions": {
                        "description": "LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /apis/v1/ads/targeting/search?dimension=jobFunction.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Language codes restricting the audience by language. Applied on Meta, Google, TikTok, LinkedIn, X, Pinterest and Reddit; rejected with 400 on OpenAI. A code the platform cannot target returns 400 listing the ones it can.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "metros": {
                        "description": "DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "regions": {
                        "description": "Region/state targeting. `key` is the platform location ID from /apis/v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`\"20321\"` is `{ key: \"20321\" }`).",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "key": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "key"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "seniorities": {
                        "description": "LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /apis/v1/ads/targeting/search?dimension=seniority.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "skills": {
                        "description": "LinkedIn B2B only. Member skills (e.g. Python, Recruiting): skill URN id fragments, or the full urn:li:skill:* URN from /apis/v1/ads/targeting/search?dimension=skill. Values are ORed; the facet is ANDed with the other facets.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "userDevice": {
                        "description": "Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "userOs": {
                        "description": "Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.",
                        "items": {
                          "minLength": 1,
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "workEmployers": {
                        "description": "Meta only. Employer entities from /apis/v1/ads/targeting/search?dimension=workEmployer.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workIndustries": {
                        "description": "Meta only. Work-industry entities from /apis/v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "workPositions": {
                        "description": "Meta only. Job title entities from /apis/v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "zips": {
                        "description": "Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.",
                        "items": {
                          "properties": {
                            "key": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "key"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "timeRangeEnd": {
                    "description": "Unix ms. Must be after start and within LinkedIn's max horizon.",
                    "type": "integer"
                  },
                  "timeRangeStart": {
                    "description": "Unix ms. Must be in the future.",
                    "type": "integer"
                  },
                  "totalBudget": {
                    "type": "number"
                  }
                },
                "required": [
                  "adAccountId",
                  "spec",
                  "timeRangeEnd",
                  "timeRangeStart"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "available": {
                      "type": "boolean"
                    },
                    "forecast": {
                      "items": {
                        "properties": {
                          "granularity": {
                            "enum": [
                              "DAILY",
                              "SEVEN_DAY",
                              "THIRTY_DAY",
                              "CUSTOM"
                            ],
                            "type": "string"
                          },
                          "metricType": {
                            "type": "string"
                          },
                          "timeSeries": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "available"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Forecast series"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Forecast ad delivery",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_linked_in_supply_forecast@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "33f801b0c36db53c334bc23cf5f684c377cc257e2b9aca4ba50aa31fb6b81918"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_targeting_supply_forecast",
          "method": "POST",
          "path": "/apis/v1/ads/targeting/supply-forecast"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_targeting_supply_forecast"
      }
    },
    "/apis/v1/ads/tiktok-identities": {
      "get": {
        "description": "Ad Creatives. Read only. Lists the identities an ad on this TikTok advertiser may run as (the profile shown on the ad): the advertiser's own TikTok accounts (TT_USER) Business Center authorized accounts (BC_AUTH_TT) custom brand identities (CUSTOMIZED_USER) Pass the chosen `identityId` on POST /apis/v1/ads/create or POST /apis/v1/ads/boost. Spark-post identities (AUTH_CODE) are not listed; a Spark code creates its own.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_tiktok_identities",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "TikTok advertiser ID",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "identities": {
                      "items": {
                        "properties": {
                          "displayName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "identityAuthorizedBcId": {
                            "description": "Business Center that authorized a BC_AUTH_TT identity",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "identityId": {
                            "type": "string"
                          },
                          "identityType": {
                            "enum": [
                              "TT_USER",
                              "BC_AUTH_TT",
                              "CUSTOMIZED_USER"
                            ],
                            "type": "string"
                          },
                          "profileImage": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "username": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Identities"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List TikTok ad identities",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ads_tik_tok_identities@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "8297ee5e649cbab28ded1a8a04d6db216edaf4bf919c4c4c903a1ac10521f97e"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_tiktok_identities",
          "method": "GET",
          "path": "/apis/v1/ads/tiktok-identities"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_tiktok_identities"
      }
    },
    "/apis/v1/ads/tiktok-smart-plus-materials": {
      "get": {
        "description": "Ad Insights. Read only. Breaks a Smart+ ad (or ad group) down by creative material, one row per Spark post, video or image, from TikTok's Smart+ material report. For a Spark post `tiktokItemId` is the TikTok post id. ### Metrics Conversion metrics are TikTok web (pixel) events.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_tiktok_smart_plus_materials",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "TikTok advertiser ID",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "YYYY-MM-DD, in the advertiser's time zone",
            "in": "query",
            "name": "startDate",
            "required": true,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "YYYY-MM-DD, on or after startDate",
            "in": "query",
            "name": "endDate",
            "required": true,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Key each row by Smart+ ad or by ad group",
            "in": "query",
            "name": "level",
            "required": false,
            "schema": {
              "default": "ad",
              "enum": [
                "ad",
                "adGroup"
              ],
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Smart+ ad ids to filter by (up to 100)",
            "in": "query",
            "name": "smartPlusAdIds",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated ad group ids to filter by (up to 100) Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "adGroupIds",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "pageSize",
            "required": false,
            "schema": {
              "default": 100,
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "endDate": {
                      "type": "string"
                    },
                    "level": {
                      "enum": [
                        "ad",
                        "adGroup"
                      ],
                      "type": "string"
                    },
                    "missingRows": {
                      "description": "Rows TikTok declared that a read and its retry could not return. 0 when the result is complete.",
                      "type": "integer"
                    },
                    "page": {
                      "type": "integer"
                    },
                    "pageSize": {
                      "type": "integer"
                    },
                    "rows": {
                      "items": {
                        "properties": {
                          "adGroupId": {
                            "description": "Set when level=adGroup",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "materialId": {
                            "description": "TikTok main material id",
                            "type": "string"
                          },
                          "materialType": {
                            "description": "e.g. VIDEO_SPARK_ADS, VIDEO, IMAGE",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "metrics": {
                            "properties": {
                              "addPaymentInfo": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "addToCart": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "clicks": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "cpc": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "impressions": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "initiateCheckout": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "purchaseValue": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "purchases": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "roas": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "spend": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              }
                            },
                            "type": "object"
                          },
                          "name": {
                            "description": "Material name or post caption",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "smartPlusAdId": {
                            "description": "Set when level=ad",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "tiktokItemId": {
                            "description": "The TikTok post id when the material is a Spark post",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "startDate": {
                      "type": "string"
                    },
                    "totalPages": {
                      "type": "integer"
                    },
                    "totalRows": {
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Material rows"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Per-creative performance inside TikTok Smart+ ads",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_tik_tok_smart_plus_material_report@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1a4b35dc168897ed001fa87cc8d7f8187b57ff39d79acfc21b824750969e8b6c"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_tiktok_smart_plus_materials",
          "method": "GET",
          "path": "/apis/v1/ads/tiktok-smart-plus-materials"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_tiktok_smart_plus_materials"
      }
    },
    "/apis/v1/ads/tiktok-smart-plus-reviews": {
      "get": {
        "description": "Ad Campaigns. Read only. Returns the review verdict of every Upgraded Smart+ ad of one TikTok advertiser, with each creative's verdict, in one paginated read. Use it to refresh reviews periodically: one call (plus its pages) per advertiser per refresh, instead of `GET /apis/v1/ads/{adId}/tiktok-smart-plus-review` per ad. 1. 2.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_tiktok_smart_plus_reviews",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "TikTok advertiser ID",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Also return Smart+ ads deleted on TikTok (listed with `primary_status: STATUS_ALL`).",
            "in": "query",
            "name": "includeDeleted",
            "required": false,
            "schema": {
              "default": false,
              "type": "boolean"
            }
          },
          {
            "description": "Freshness window in seconds. Reviews, refusals and the listing read within it are served without calling TikTok; older ones are still returned but read again, oldest first.",
            "in": "query",
            "name": "maxAgeSeconds",
            "required": false,
            "schema": {
              "default": 3600,
              "maximum": 86400,
              "minimum": 600,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "pageSize",
            "required": false,
            "schema": {
              "default": 500,
              "maximum": 1000,
              "minimum": 1,
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "allFresh": {
                      "description": "True when every item and refusal of this page was read within `maxAgeSeconds` and nothing is pending.",
                      "type": "boolean"
                    },
                    "counts": {
                      "description": "The Smart+ ads on this page split by state; the four counts add up to the Smart+ ads on this page (fewer than `pageSize` on the last page).",
                      "properties": {
                        "failed": {
                          "description": "Entries of `failedSmartPlusAds`.",
                          "type": "integer"
                        },
                        "fresh": {
                          "description": "Items read within `maxAgeSeconds`.",
                          "type": "integer"
                        },
                        "pending": {
                          "description": "Smart+ ads never read (`pendingSmartPlusAdIds`).",
                          "type": "integer"
                        },
                        "stale": {
                          "description": "Items read earlier, returned with their `readAt` and due for a refresh.",
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "failedSmartPlusAds": {
                      "description": "Smart+ ads of this page whose review TikTok refused on its own (e.g. an ad deleted on TikTok since the listing was read). Empty when none.",
                      "items": {
                        "properties": {
                          "adGroupId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "error": {
                            "properties": {
                              "message": {
                                "description": "TikTok's error message, verbatim.",
                                "type": "string"
                              },
                              "tiktokCode": {
                                "description": "TikTok's error code, verbatim.",
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              }
                            },
                            "type": "object"
                          },
                          "refusedAt": {
                            "description": "When TikTok refused this ad. Null for a refusal stored before this field existed.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "smartPlusAdId": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "includeDeleted": {
                      "type": "boolean"
                    },
                    "incomplete": {
                      "description": "True while some Smart+ ads of this page were never read (`counts.pending > 0`). Stale items alone keep it false.",
                      "type": "boolean"
                    },
                    "items": {
                      "items": {
                        "properties": {
                          "adGroupId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "materials": {
                            "description": "One entry per creative TikTok reviewed (`material_review_infos`).",
                            "items": {
                              "additionalProperties": true,
                              "description": "The verdict of one creative of a Smart+ ad (`material_review_infos`).",
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "readAt": {
                            "description": "When the verdict was read from TikTok, kept as is when served from the store. Older than `maxAgeSeconds` means stale.",
                            "format": "date-time",
                            "type": "string"
                          },
                          "review": {
                            "description": "The ad-level verdict of a Smart+ ad (`smart_plus_ad_review_infos`). Null when TikTok returned none.",
                            "properties": {
                              "appealRejectReasons": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "appealStatus": {
                                "description": "TikTok `appeal_status`, verbatim: NOT_APPEALED, APPEALING, APPEAL_SUCCESSFUL, APPEAL_FAILED, APPEAL_DONE.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "passedLocations": {
                                "description": "Location codes that passed the review.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "rawReviewStatus": {
                                "description": "TikTok `review_status`, verbatim.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "rejectReasons": {
                                "description": "Every distinct reason across `rejections`.",
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "rejections": {
                                "items": {
                                  "additionalProperties": true,
                                  "description": "One TikTok `reject_info` entry.",
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "reviewStatus": {
                                "description": "TikTok `review_status` normalized: ALL_AVAILABLE -> approved, PART_AVAILABLE -> partially_approved (delivers in part of the targeted locations), UNAVAILABLE -> rejected, anything else or missing -> unknown (see `rawReviewStatus`).",
                                "enum": [
                                  "approved",
                                  "partially_approved",
                                  "rejected",
                                  "unknown"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "smartPlusAdId": {
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "listing": {
                      "description": "The Smart+ ad listing this page was cut from.",
                      "properties": {
                        "error": {
                          "description": "The relist error on a fallback, otherwise null.",
                          "properties": {
                            "message": {
                              "type": "string"
                            },
                            "tiktokCode": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "readAt": {
                          "description": "When the listing was read from TikTok.",
                          "format": "date-time",
                          "type": "string"
                        },
                        "source": {
                          "description": "`fresh`: read within `maxAgeSeconds`. `fallback`: relisting failed and this is the older stored listing.",
                          "enum": [
                            "fresh",
                            "fallback"
                          ],
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "maxAgeSeconds": {
                      "description": "The freshness window this page was read with.",
                      "type": "integer"
                    },
                    "oldestReadAt": {
                      "description": "The oldest `readAt` in `items`. Null when `items` is empty.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "page": {
                      "type": "integer"
                    },
                    "pageSize": {
                      "type": "integer"
                    },
                    "pendingSmartPlusAdIds": {
                      "description": "Smart+ ads of this page never read. Empty when every ad has a stored review or refusal.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "refreshState": {
                      "description": "Whether this request could refresh the due (stale or pending) Smart+ ads of the page. Carries `retryAfterSeconds`.",
                      "enum": [
                        "ok",
                        "paused",
                        "refused",
                        "error"
                      ],
                      "type": "string"
                    },
                    "retryAfterSeconds": {
                      "description": "Set exactly when `refreshState` is `paused` or `refused`, including stale items with nothing pending. Always equals the `Retry-After` header, which is sent exactly when this is not null. Client rule:",
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "reviewError": {
                      "description": "Set when TikTok refused both halves of a review batch the same way (for example a permission error) and the page was served from stored reviews instead of being refreshed. Null otherwise.",
                      "properties": {
                        "message": {
                          "type": "string"
                        },
                        "tiktokCode": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "totalPages": {
                      "type": "integer"
                    },
                    "totalSmartPlusAds": {
                      "description": "Smart+ ads of the advertiser across all pages.",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The reviews of one page of the advertiser's Smart+ ads. Check `incomplete`: when true, some Smart+ ads of the page were never read. `allFresh` says whether every review is within `maxAgeSeconds`."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Review status of every TikTok Smart+ ad of an advertiser",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_tik_tok_smart_plus_reviews@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "ce098fee8e14d24d9ae940e93a164077e2a3409819aae8d3a0a6148ad079c1ce"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_tiktok_smart_plus_reviews",
          "method": "GET",
          "path": "/apis/v1/ads/tiktok-smart-plus-reviews"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_tiktok_smart_plus_reviews"
      }
    },
    "/apis/v1/ads/timeline": {
      "get": {
        "description": "Ad Campaigns. Read only. Returns an ads account's spend, results and other metrics day by day, ready for a daily performance chart. ### Parameters `connectionId` is required. The lookup is sibling-expanded, so passing the `metaads` ID also includes ads under the linked `facebook` / `instagram` posting account (and vice-versa), the same convention as `/apis/v1/ads/tree` and `/apis/v1/ads`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_timeline",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Optional platform-native ad account ID (e.g. Meta `act_…`, TikTok advertiser ID). Use when the connection wraps multiple platform ad accounts and the chart should show one only.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Inclusive start of metrics range (YYYY-MM-DD). Defaults to 90 days ago.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Inclusive end of metrics range (YYYY-MM-DD). Defaults to today. Max 730-day range.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Restrict to one platform.",
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "microsoft",
                "meta",
                "x"
              ],
              "type": "string"
            }
          },
          {
            "description": "Set to `previous` to also return `previousRows` for the period of the same length that ends the day before `fromDate`, with that period as `previousRange`. Needs a `fromDate` (sent or defaulted); `toDate` alone answers 400.",
            "in": "query",
            "name": "compare",
            "required": false,
            "schema": {
              "enum": [
                "previous"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "backfillPending": {
                      "description": "Meta only. Present and true while historical data is being backfilled.",
                      "type": "boolean"
                    },
                    "previousRange": {
                      "description": "Only with `compare=previous`. The period of the same length that ends the day before `fromDate`.",
                      "properties": {
                        "fromDate": {
                          "format": "date",
                          "type": "string"
                        },
                        "toDate": {
                          "format": "date",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "previousRows": {
                      "description": "Only with `compare=previous`. The daily rows of `previousRange`, in the same shape as `rows`.",
                      "items": {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "rows": {
                      "items": {
                        "properties": {
                          "actionValues": {
                            "additionalProperties": {
                              "type": "number"
                            },
                            "description": "Monetary mirror of `actions` in native currency.",
                            "type": "object"
                          },
                          "actions": {
                            "additionalProperties": {
                              "type": "number"
                            },
                            "description": "Per-action-type counts merged across all ads on this day. Keys are platform-native action types.",
                            "type": "object"
                          },
                          "allConversions": {
                            "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                            "type": "number"
                          },
                          "clicks": {
                            "type": "integer"
                          },
                          "conversions": {
                            "description": "Sum of conversion events over the range. Fractional values are normal (attribution splitting + Google modeled conversions). Meta: the ad set Ads Manager Results (see AdMetrics.conversions). Google: tracked conversions.",
                            "type": "number"
                          },
                          "costPerConversion": {
                            "type": "number"
                          },
                          "cpc": {
                            "description": "Cost per click in native currency.",
                            "type": "number"
                          },
                          "cpm": {
                            "description": "Cost per 1000 impressions in native currency.",
                            "type": "number"
                          },
                          "ctr": {
                            "description": "Click-through rate as a percentage (0 to 100).",
                            "type": "number"
                          },
                          "currency": {
                            "description": "ISO 4217 currency of every money field in this row (spend, cpc, cpm, costPerConversion, purchaseValue, actionValues). Null when the currency of the row's ad accounts is unknown. Added 2026-10-23.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "date": {
                            "format": "date",
                            "type": "string"
                          },
                          "engagement": {
                            "type": "integer"
                          },
                          "impressions": {
                            "type": "integer"
                          },
                          "purchaseValue": {
                            "description": "Sum of purchase-type action values on this day, native currency.",
                            "type": "number"
                          },
                          "reach": {
                            "description": "Reach summed across the account's ads for this single day. A person seen by two ads the same day counts twice, and reach is de-duplicated per day only: do NOT sum it across days (people reached on multiple days would be double-counted).",
                            "type": "integer"
                          },
                          "roas": {
                            "description": "Derived purchaseValue / spend.",
                            "type": "number"
                          },
                          "spend": {
                            "description": "Native currency units (matches /ads/tree convention), in `currency`.",
                            "type": "number"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Daily time series of aggregate metrics. Empty `rows` means the account has no ad activity in the range."
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "backfillPending": {
                      "description": "Always true on this response. Part of the requested range is still being backfilled; retry until the request returns 200.",
                      "type": "boolean"
                    },
                    "previousRange": {
                      "description": "Only with `compare=previous`. The period of the same length that ends the day before `fromDate`.",
                      "properties": {
                        "fromDate": {
                          "format": "date",
                          "type": "string"
                        },
                        "toDate": {
                          "format": "date",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "previousRows": {
                      "description": "Only with `compare=previous`. The daily rows of `previousRange`, in the same shape as `rows`.",
                      "items": {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "rows": {
                      "items": {
                        "properties": {
                          "actionValues": {
                            "additionalProperties": {
                              "type": "number"
                            },
                            "description": "Monetary mirror of `actions` in native currency.",
                            "type": "object"
                          },
                          "actions": {
                            "additionalProperties": {
                              "type": "number"
                            },
                            "description": "Per-action-type counts merged across all ads on this day. Keys are platform-native action types.",
                            "type": "object"
                          },
                          "allConversions": {
                            "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                            "type": "number"
                          },
                          "clicks": {
                            "type": "integer"
                          },
                          "conversions": {
                            "description": "Sum of conversion events over the range. Fractional values are normal (attribution splitting + Google modeled conversions). Meta: the ad set Ads Manager Results (see AdMetrics.conversions). Google: tracked conversions.",
                            "type": "number"
                          },
                          "costPerConversion": {
                            "type": "number"
                          },
                          "cpc": {
                            "description": "Cost per click in native currency.",
                            "type": "number"
                          },
                          "cpm": {
                            "description": "Cost per 1000 impressions in native currency.",
                            "type": "number"
                          },
                          "ctr": {
                            "description": "Click-through rate as a percentage (0 to 100).",
                            "type": "number"
                          },
                          "currency": {
                            "description": "ISO 4217 currency of every money field in this row (spend, cpc, cpm, costPerConversion, purchaseValue, actionValues). Null when the currency of the row's ad accounts is unknown. Added 2026-10-23.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "date": {
                            "format": "date",
                            "type": "string"
                          },
                          "engagement": {
                            "type": "integer"
                          },
                          "impressions": {
                            "type": "integer"
                          },
                          "purchaseValue": {
                            "description": "Sum of purchase-type action values on this day, native currency.",
                            "type": "number"
                          },
                          "reach": {
                            "description": "Reach summed across the account's ads for this single day. A person seen by two ads the same day counts twice, and reach is de-duplicated per day only: do NOT sum it across days (people reached on multiple days would be double-counted).",
                            "type": "integer"
                          },
                          "roas": {
                            "description": "Derived purchaseValue / spend.",
                            "type": "number"
                          },
                          "spend": {
                            "description": "Native currency units (matches /ads/tree convention), in `currency`.",
                            "type": "number"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    }
                  },
                  "required": [
                    "backfillPending"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Meta only. Historical data is incomplete and backfill remains pending."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get daily account metrics",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ads_timeline@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "023509ce760fdd43dfcd250eea7a5cfa4b9b092b4848b1f3c2a1359c24400608"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_timeline",
          "method": "GET",
          "path": "/apis/v1/ads/timeline"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_timeline"
      }
    },
    "/apis/v1/ads/tree": {
      "get": {
        "description": "Ad Campaigns. Read only. Shows your campaigns with their ad sets and ads nested inside, with spend and results rolled up at every level. ### How it aggregates Uses a two-stage aggregation: ads are grouped into ad sets, then ad sets into campaigns. Metrics are computed over an optional date range, then rolled up from ad level to ad set and campaign levels. Pagination is at the campaign level.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_tree",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Page number (1-based)",
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Campaigns per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Matches the web UI's default view. Status is NOT filtered by default; use the `status` param for that.",
            "in": "query",
            "name": "source",
            "required": false,
            "schema": {
              "default": "all",
              "enum": [
                "aisa",
                "all"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "platform",
            "required": false,
            "schema": {
              "enum": [
                "facebook",
                "instagram",
                "tiktok",
                "linkedin",
                "pinterest",
                "google",
                "twitter",
                "openai",
                "reddit",
                "microsoft",
                "meta",
                "x"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter by derived campaign status (post-aggregation)",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "enum": [
                "active",
                "paused",
                "pending_review",
                "rejected",
                "completed",
                "cancelled",
                "error"
              ],
              "type": "string"
            }
          },
          {
            "description": "Comma-separate for multiple (`?adAccountId=act_1,act_2,act_3`); a single value keeps its old shape. Max 50 accounts per request.",
            "in": "query",
            "name": "adAccountId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Meta only: Facebook Page ID. Prunes the tree to ads whose creative is backed by this Page: campaigns and ad sets with no ad on the Page drop out, and rolled-up metrics cover only the Page's ads.",
            "in": "query",
            "name": "pageId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Restrict the tree to one or more campaigns by platform campaign id (the id the platform assigns, e.g. Meta's numeric campaign id). Comma-separate up to 100 ids (`?campaignId=123,456`). Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
            "in": "query",
            "name": "campaignId",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Returns only campaigns with a change stored since this time (ISO 8601 with offset, e.g. `2026-09-30T10:00:00Z`). Each matching campaign comes back whole (every ad set and ad).",
            "in": "query",
            "name": "updatedSince",
            "required": false,
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Case-insensitive substring match on campaign, ad set and ad names (`_`, `%` and spaces match literally), or an exact platform campaign, ad set or ad id. A campaign whose name matches returns with all its ad sets and ads.",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "maxLength": 500,
              "type": "string"
            }
          },
          {
            "description": "Start of the METRICS date range (YYYY-MM-DD). On its own it affects only the spend/impression numbers overlaid on each node, not which campaigns are returned. Pass `hasDelivery` or `minSpend` to also filter the campaign set to this window.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End of metrics date range (YYYY-MM-DD). Defaults to today. Max 730-day range.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Return only campaigns that delivered between `fromDate` and `toDate`: spend above zero, or impressions served at zero spend.",
            "in": "query",
            "name": "hasDelivery",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Return only campaigns whose spend between `fromDate` and `toDate` reaches this amount.",
            "in": "query",
            "name": "minSpend",
            "required": false,
            "schema": {
              "minimum": 0,
              "type": "number"
            }
          },
          {
            "description": "Campaign-level sort order. `newest` (default) / `oldest` order by the campaign's newest-ad createdAt. `spend_desc` / `spend_asc` order by aggregated spend in the requested date range; campaigns with no spend land at the end.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "default": "newest",
              "enum": [
                "newest",
                "oldest",
                "spend_desc",
                "spend_asc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Set to `1` to also return a daily breakdown (mirrors Meta Insights' `time_increment=1`). Only `1` (daily) is supported. See `dailyLevel` to control which levels carry it.",
            "in": "query",
            "name": "timeIncrement",
            "required": false,
            "schema": {
              "enum": [
                1
              ],
              "type": "integer"
            }
          },
          {
            "description": "Which tree levels get the `daily[]` series when `timeIncrement=1`. Ignored when `timeIncrement` is unset. `campaign` (default): on campaign nodes only. The common per-campaign-trend case, and the smallest payload. `adset`: on ad sets too.",
            "in": "query",
            "name": "dailyLevel",
            "required": false,
            "schema": {
              "default": "campaign",
              "enum": [
                "campaign",
                "adset",
                "ad"
              ],
              "type": "string"
            }
          },
          {
            "description": "Set to `previous` to also read the period of the same length that ends the day before `fromDate`.",
            "in": "query",
            "name": "compare",
            "required": false,
            "schema": {
              "enum": [
                "previous"
              ],
              "type": "string"
            }
          },
          {
            "description": "Set to `true` to add your own results (see Campaign results): every campaign gains `results`, the values you sent for the range plus each formula they allow, and the response gains `resultMetrics` to label them.",
            "in": "query",
            "name": "results",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "backfillPending": {
                      "description": "Meta only. Present and true while historical data is being backfilled.",
                      "type": "boolean"
                    },
                    "campaigns": {
                      "items": {
                        "description": "Campaign with nested ad sets and rolled-up metrics",
                        "properties": {
                          "adCount": {
                            "description": "Total ads across all ad sets",
                            "type": "integer"
                          },
                          "adSetCount": {
                            "type": "integer"
                          },
                          "adSets": {
                            "items": {
                              "additionalProperties": true,
                              "description": "Ad set (or ad group/line item depending on platform) with rolled-up metrics and child ads",
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "advertisingChannelType": {
                            "description": "Google-only. Raw campaign.advertising_channel_type (SEARCH, PERFORMANCE_MAX, LOCAL_SERVICES, VIDEO, DEMAND_GEN, DISPLAY, SHOPPING, ...). Serving surface, distinct from platformObjective (advertiser intent).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "bidAmount": {
                            "description": "Representative bid for the campaign, bubbled up from the top-spending ad set (whole currency units). Meta: populated when the ad-set bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "bidStrategy": {
                            "anyOf": [
                              {
                                "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                                "enum": [
                                  "LOWEST_COST_WITHOUT_CAP",
                                  "LOWEST_COST_WITH_BID_CAP",
                                  "COST_CAP",
                                  "LOWEST_COST_WITH_MIN_ROAS"
                                ],
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Campaign-level bid strategy. Ad sets inherit this unless they override."
                          },
                          "budget": {
                            "description": "Effective budget (back-compat). For CBO this mirrors `campaignBudget`, for ABO this mirrors the child ad-set budget. Use `budgetLevel` to disambiguate.",
                            "properties": {
                              "amount": {
                                "type": "number"
                              },
                              "type": {
                                "enum": [
                                  "daily",
                                  "lifetime"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "budgetLevel": {
                            "description": "Canonical CBO/ABO indicator. `campaign` = CBO (Advantage Campaign Budget, budget lives on the campaign). `adset` = ABO (budget lives on each ad set). Route budget updates to the matching Meta entity.",
                            "enum": [
                              "campaign",
                              "adset"
                            ],
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignBudget": {
                            "description": "Campaign-level budget (Campaign Budget Optimization / CBO). Populated only when the platform set the budget at the campaign level. For ABO campaigns this is null and the budget lives on the child ad set.",
                            "properties": {
                              "amount": {
                                "type": "number"
                              },
                              "type": {
                                "enum": [
                                  "daily",
                                  "lifetime"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "campaignIssuesInfo": {
                            "description": "Platform-reported campaign issues (Meta `issues_info[]`). Populated only when the platform has delivery issues to report; contains the specific error codes and messages.",
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": [
                              "array",
                              "null"
                            ]
                          },
                          "campaignName": {
                            "type": "string"
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdTime": {
                            "description": "Not the platform campaign's own creation time (Meta's `Campaign.created_time` etc. is not synced). A campaign created empty and populated later shows its first ad's time, not the campaign's.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "currency": {
                            "description": "ISO 4217 currency code (e.g. USD, EUR, CLP, JPY) for all budget amounts in this campaign node. Budgets are NOT normalized to USD.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "daily": {
                            "description": "Per-day metric series for this campaign. Present only when `GET /apis/v1/ads/tree` is called with `timeIncrement=1` (any `dailyLevel`). This is the per-campaign daily trend.",
                            "items": {
                              "additionalProperties": true,
                              "description": "One day of metrics: the same fields as `AdMetrics` plus the `date` they apply to. Returned inside a node's `daily[]` when `GET /apis/v1/ads/tree` is called with `timeIncrement=1`.",
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "isBudgetScheduleEnabled": {
                            "default": false,
                            "description": "Meta-only. Mirrors Campaign.is_budget_schedule_enabled: true when the campaign uses budget scheduling (time-based budget changes). Independent of CBO/ABO.",
                            "type": "boolean"
                          },
                          "isSmartPlus": {
                            "description": "TikTok only. true when the campaign is an Upgraded Smart+ campaign (TikTok lists it on /smart_plus/campaign/get/), false when it is not.",
                            "type": "boolean"
                          },
                          "metrics": {
                            "properties": {
                              "actionValues": {
                                "additionalProperties": true,
                                "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                "type": "object"
                              },
                              "actions": {
                                "additionalProperties": true,
                                "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                "type": "object"
                              },
                              "allConversions": {
                                "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                "type": "number"
                              },
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                "type": "number"
                              },
                              "costPerAction": {
                                "additionalProperties": true,
                                "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                "type": "object"
                              },
                              "costPerConversion": {
                                "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                "type": "number"
                              },
                              "costPerThruplay": {
                                "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                "type": "number"
                              },
                              "cpc": {
                                "description": "Cost per click",
                                "type": "number"
                              },
                              "cpm": {
                                "description": "Cost per 1000 impressions",
                                "type": "number"
                              },
                              "ctr": {
                                "description": "Click-through rate (%)",
                                "type": "number"
                              },
                              "engagement": {
                                "type": "integer"
                              },
                              "engagementBreakdown": {
                                "additionalProperties": true,
                                "description": "The single `engagement` total, split into the interactions behind it.",
                                "type": "object"
                              },
                              "funnel": {
                                "additionalProperties": true,
                                "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                "type": "object"
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "inlineLinkClickCtr": {
                                "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "inlineLinkClicks": {
                                "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                "type": "integer"
                              },
                              "lastSyncedAt": {
                                "description": "Present on individual ads only, not on campaign aggregations",
                                "format": "date-time",
                                "type": "string"
                              },
                              "outboundClicks": {
                                "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                "type": "integer"
                              },
                              "outboundClicksCtr": {
                                "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "purchaseValue": {
                                "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                "type": "number"
                              },
                              "reach": {
                                "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                "type": "integer"
                              },
                              "roas": {
                                "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                "type": "number"
                              },
                              "spend": {
                                "type": "number"
                              },
                              "uniqueClicks": {
                                "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                "type": "integer"
                              },
                              "uniqueCtr": {
                                "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                "type": "number"
                              },
                              "video2SecWatchedActions": {
                                "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                "type": "integer"
                              },
                              "video30SecWatchedActions": {
                                "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                "type": "integer"
                              },
                              "video6SecFocusedViews": {
                                "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                "type": "integer"
                              },
                              "video6SecWatchedActions": {
                                "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                "type": "integer"
                              },
                              "videoAvgTimeWatchedActions": {
                                "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                "type": "number"
                              },
                              "videoP100WatchedActions": {
                                "description": "Views reaching 100% of the video's length.",
                                "type": "integer"
                              },
                              "videoP25WatchedActions": {
                                "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                "type": "integer"
                              },
                              "videoP50WatchedActions": {
                                "description": "Views reaching 50% of the video's length.",
                                "type": "integer"
                              },
                              "videoP75WatchedActions": {
                                "description": "Views reaching 75% of the video's length.",
                                "type": "integer"
                              },
                              "videoP95WatchedActions": {
                                "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                "type": "integer"
                              },
                              "videoPlayActions": {
                                "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                "type": "integer"
                              },
                              "videoThruplayWatchedActions": {
                                "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "optimizationGoal": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              }
                            ],
                            "description": "The ad sets' optimization goal. A single string when every ad set shares one goal. A JSON array of the distinct goals when ad sets differ (never a comma-joined string). Element order is not guaranteed; treat it as an unordered set."
                          },
                          "platform": {
                            "enum": [
                              "facebook",
                              "instagram",
                              "tiktok",
                              "linkedin",
                              "pinterest",
                              "google",
                              "twitter",
                              "openai",
                              "reddit",
                              "microsoft"
                            ],
                            "type": "string"
                          },
                          "platformAdAccountId": {
                            "type": "string"
                          },
                          "platformAdAccountName": {
                            "description": "Human-readable advertiser/account name from the platform. Refreshed on every sync.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformCampaignId": {
                            "type": "string"
                          },
                          "platformCampaignStatus": {
                            "description": "Raw platform-level campaign status (Meta `effective_status`: ACTIVE, PAUSED, DELETED, ARCHIVED, IN_PROCESS, WITH_ISSUES; ChatGPT (OpenAI): the campaign's own switch, active / paused / archived, independent of the delivery `status`; TikTok…",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformObjective": {
                            "description": "Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC)",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "previousMetrics": {
                            "description": "Only with `compare=previous`. The same metrics over `previousRange`.",
                            "properties": {
                              "actionValues": {
                                "additionalProperties": true,
                                "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                "type": "object"
                              },
                              "actions": {
                                "additionalProperties": true,
                                "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                "type": "object"
                              },
                              "allConversions": {
                                "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                "type": "number"
                              },
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                "type": "number"
                              },
                              "costPerAction": {
                                "additionalProperties": true,
                                "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                "type": "object"
                              },
                              "costPerConversion": {
                                "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                "type": "number"
                              },
                              "costPerThruplay": {
                                "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                "type": "number"
                              },
                              "cpc": {
                                "description": "Cost per click",
                                "type": "number"
                              },
                              "cpm": {
                                "description": "Cost per 1000 impressions",
                                "type": "number"
                              },
                              "ctr": {
                                "description": "Click-through rate (%)",
                                "type": "number"
                              },
                              "engagement": {
                                "type": "integer"
                              },
                              "engagementBreakdown": {
                                "additionalProperties": true,
                                "description": "The single `engagement` total, split into the interactions behind it.",
                                "type": "object"
                              },
                              "funnel": {
                                "additionalProperties": true,
                                "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                "type": "object"
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "inlineLinkClickCtr": {
                                "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "inlineLinkClicks": {
                                "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                "type": "integer"
                              },
                              "lastSyncedAt": {
                                "description": "Present on individual ads only, not on campaign aggregations",
                                "format": "date-time",
                                "type": "string"
                              },
                              "outboundClicks": {
                                "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                "type": "integer"
                              },
                              "outboundClicksCtr": {
                                "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "purchaseValue": {
                                "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                "type": "number"
                              },
                              "reach": {
                                "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                "type": "integer"
                              },
                              "roas": {
                                "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                "type": "number"
                              },
                              "spend": {
                                "type": "number"
                              },
                              "uniqueClicks": {
                                "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                "type": "integer"
                              },
                              "uniqueCtr": {
                                "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                "type": "number"
                              },
                              "video2SecWatchedActions": {
                                "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                "type": "integer"
                              },
                              "video30SecWatchedActions": {
                                "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                "type": "integer"
                              },
                              "video6SecFocusedViews": {
                                "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                "type": "integer"
                              },
                              "video6SecWatchedActions": {
                                "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                "type": "integer"
                              },
                              "videoAvgTimeWatchedActions": {
                                "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                "type": "number"
                              },
                              "videoP100WatchedActions": {
                                "description": "Views reaching 100% of the video's length.",
                                "type": "integer"
                              },
                              "videoP25WatchedActions": {
                                "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                "type": "integer"
                              },
                              "videoP50WatchedActions": {
                                "description": "Views reaching 50% of the video's length.",
                                "type": "integer"
                              },
                              "videoP75WatchedActions": {
                                "description": "Views reaching 75% of the video's length.",
                                "type": "integer"
                              },
                              "videoP95WatchedActions": {
                                "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                "type": "integer"
                              },
                              "videoPlayActions": {
                                "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                "type": "integer"
                              },
                              "videoThruplayWatchedActions": {
                                "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "promotedObject": {
                            "description": "Meta promoted object at campaign level (conversion event details)",
                            "properties": {
                              "custom_event_type": {
                                "type": "string"
                              },
                              "page_id": {
                                "type": "string"
                              },
                              "pixel_id": {
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "results": {
                            "additionalProperties": {
                              "type": "number"
                            },
                            "description": "Only with `results=true`. The values you sent for this campaign over the range, plus each formula they allow, by metric key. A metric with no value is absent.",
                            "type": "object"
                          },
                          "reviewStatus": {
                            "anyOf": [
                              {
                                "description": "Platform-side review state, independent of the delivery `status` and the `configuredStatus` on/off toggle. `in_review` means the platform is still reviewing. Absent when the platform reports no review signal (e.g.",
                                "enum": [
                                  "in_review",
                                  "approved",
                                  "rejected",
                                  "with_issues"
                                ],
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Platform-side review state of the campaign."
                          },
                          "roasAverageFloor": {
                            "description": "Representative ROAS floor for the campaign, bubbled up from the top-spending ad set. Decimal multiplier (2.0 = 2.0x).",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "status": {
                            "description": "Delivery status derived from child ad statuses. Distinct from `reviewStatus`, which reflects the platform-side review state.",
                            "enum": [
                              "active",
                              "paused",
                              "pending_review",
                              "rejected",
                              "completed",
                              "cancelled",
                              "error"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "pagination": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "previousRange": {
                      "description": "Only with `compare=previous`. The range `previousMetrics` covers.",
                      "properties": {
                        "fromDate": {
                          "format": "date",
                          "type": "string"
                        },
                        "toDate": {
                          "format": "date",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "syncedAt": {
                      "description": "When the most recently synced ad on this page was last read from the platform. Null before the first sync.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Nested campaign tree with pagination"
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "backfillPending": {
                      "description": "Always true on this response. Part of the requested range is still being backfilled; retry until the request returns 200.",
                      "type": "boolean"
                    },
                    "campaigns": {
                      "items": {
                        "description": "Campaign with nested ad sets and rolled-up metrics",
                        "properties": {
                          "adCount": {
                            "description": "Total ads across all ad sets",
                            "type": "integer"
                          },
                          "adSetCount": {
                            "type": "integer"
                          },
                          "adSets": {
                            "items": {
                              "additionalProperties": true,
                              "description": "Ad set (or ad group/line item depending on platform) with rolled-up metrics and child ads",
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "advertisingChannelType": {
                            "description": "Google-only. Raw campaign.advertising_channel_type (SEARCH, PERFORMANCE_MAX, LOCAL_SERVICES, VIDEO, DEMAND_GEN, DISPLAY, SHOPPING, ...). Serving surface, distinct from platformObjective (advertiser intent).",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "bidAmount": {
                            "description": "Representative bid for the campaign, bubbled up from the top-spending ad set (whole currency units). Meta: populated when the ad-set bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP.",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "bidStrategy": {
                            "anyOf": [
                              {
                                "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                                "enum": [
                                  "LOWEST_COST_WITHOUT_CAP",
                                  "LOWEST_COST_WITH_BID_CAP",
                                  "COST_CAP",
                                  "LOWEST_COST_WITH_MIN_ROAS"
                                ],
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Campaign-level bid strategy. Ad sets inherit this unless they override."
                          },
                          "budget": {
                            "description": "Effective budget (back-compat). For CBO this mirrors `campaignBudget`, for ABO this mirrors the child ad-set budget. Use `budgetLevel` to disambiguate.",
                            "properties": {
                              "amount": {
                                "type": "number"
                              },
                              "type": {
                                "enum": [
                                  "daily",
                                  "lifetime"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "budgetLevel": {
                            "description": "Canonical CBO/ABO indicator. `campaign` = CBO (Advantage Campaign Budget, budget lives on the campaign). `adset` = ABO (budget lives on each ad set). Route budget updates to the matching Meta entity.",
                            "enum": [
                              "campaign",
                              "adset"
                            ],
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignBudget": {
                            "description": "Campaign-level budget (Campaign Budget Optimization / CBO). Populated only when the platform set the budget at the campaign level. For ABO campaigns this is null and the budget lives on the child ad set.",
                            "properties": {
                              "amount": {
                                "type": "number"
                              },
                              "type": {
                                "enum": [
                                  "daily",
                                  "lifetime"
                                ],
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "campaignIssuesInfo": {
                            "description": "Platform-reported campaign issues (Meta `issues_info[]`). Populated only when the platform has delivery issues to report; contains the specific error codes and messages.",
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": [
                              "array",
                              "null"
                            ]
                          },
                          "campaignName": {
                            "type": "string"
                          },
                          "connectionId": {
                            "description": "The ads connection (adc_...) the object belongs to.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdTime": {
                            "description": "Not the platform campaign's own creation time (Meta's `Campaign.created_time` etc. is not synced). A campaign created empty and populated later shows its first ad's time, not the campaign's.",
                            "format": "date-time",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "currency": {
                            "description": "ISO 4217 currency code (e.g. USD, EUR, CLP, JPY) for all budget amounts in this campaign node. Budgets are NOT normalized to USD.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "daily": {
                            "description": "Per-day metric series for this campaign. Present only when `GET /apis/v1/ads/tree` is called with `timeIncrement=1` (any `dailyLevel`). This is the per-campaign daily trend.",
                            "items": {
                              "additionalProperties": true,
                              "description": "One day of metrics: the same fields as `AdMetrics` plus the `date` they apply to. Returned inside a node's `daily[]` when `GET /apis/v1/ads/tree` is called with `timeIncrement=1`.",
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "isBudgetScheduleEnabled": {
                            "default": false,
                            "description": "Meta-only. Mirrors Campaign.is_budget_schedule_enabled: true when the campaign uses budget scheduling (time-based budget changes). Independent of CBO/ABO.",
                            "type": "boolean"
                          },
                          "isSmartPlus": {
                            "description": "TikTok only. true when the campaign is an Upgraded Smart+ campaign (TikTok lists it on /smart_plus/campaign/get/), false when it is not.",
                            "type": "boolean"
                          },
                          "metrics": {
                            "properties": {
                              "actionValues": {
                                "additionalProperties": true,
                                "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                "type": "object"
                              },
                              "actions": {
                                "additionalProperties": true,
                                "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                "type": "object"
                              },
                              "allConversions": {
                                "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                "type": "number"
                              },
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                "type": "number"
                              },
                              "costPerAction": {
                                "additionalProperties": true,
                                "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                "type": "object"
                              },
                              "costPerConversion": {
                                "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                "type": "number"
                              },
                              "costPerThruplay": {
                                "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                "type": "number"
                              },
                              "cpc": {
                                "description": "Cost per click",
                                "type": "number"
                              },
                              "cpm": {
                                "description": "Cost per 1000 impressions",
                                "type": "number"
                              },
                              "ctr": {
                                "description": "Click-through rate (%)",
                                "type": "number"
                              },
                              "engagement": {
                                "type": "integer"
                              },
                              "engagementBreakdown": {
                                "additionalProperties": true,
                                "description": "The single `engagement` total, split into the interactions behind it.",
                                "type": "object"
                              },
                              "funnel": {
                                "additionalProperties": true,
                                "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                "type": "object"
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "inlineLinkClickCtr": {
                                "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "inlineLinkClicks": {
                                "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                "type": "integer"
                              },
                              "lastSyncedAt": {
                                "description": "Present on individual ads only, not on campaign aggregations",
                                "format": "date-time",
                                "type": "string"
                              },
                              "outboundClicks": {
                                "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                "type": "integer"
                              },
                              "outboundClicksCtr": {
                                "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "purchaseValue": {
                                "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                "type": "number"
                              },
                              "reach": {
                                "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                "type": "integer"
                              },
                              "roas": {
                                "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                "type": "number"
                              },
                              "spend": {
                                "type": "number"
                              },
                              "uniqueClicks": {
                                "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                "type": "integer"
                              },
                              "uniqueCtr": {
                                "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                "type": "number"
                              },
                              "video2SecWatchedActions": {
                                "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                "type": "integer"
                              },
                              "video30SecWatchedActions": {
                                "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                "type": "integer"
                              },
                              "video6SecFocusedViews": {
                                "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                "type": "integer"
                              },
                              "video6SecWatchedActions": {
                                "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                "type": "integer"
                              },
                              "videoAvgTimeWatchedActions": {
                                "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                "type": "number"
                              },
                              "videoP100WatchedActions": {
                                "description": "Views reaching 100% of the video's length.",
                                "type": "integer"
                              },
                              "videoP25WatchedActions": {
                                "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                "type": "integer"
                              },
                              "videoP50WatchedActions": {
                                "description": "Views reaching 50% of the video's length.",
                                "type": "integer"
                              },
                              "videoP75WatchedActions": {
                                "description": "Views reaching 75% of the video's length.",
                                "type": "integer"
                              },
                              "videoP95WatchedActions": {
                                "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                "type": "integer"
                              },
                              "videoPlayActions": {
                                "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                "type": "integer"
                              },
                              "videoThruplayWatchedActions": {
                                "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "optimizationGoal": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              }
                            ],
                            "description": "The ad sets' optimization goal. A single string when every ad set shares one goal. A JSON array of the distinct goals when ad sets differ (never a comma-joined string). Element order is not guaranteed; treat it as an unordered set."
                          },
                          "platform": {
                            "enum": [
                              "facebook",
                              "instagram",
                              "tiktok",
                              "linkedin",
                              "pinterest",
                              "google",
                              "twitter",
                              "openai",
                              "reddit",
                              "microsoft"
                            ],
                            "type": "string"
                          },
                          "platformAdAccountId": {
                            "type": "string"
                          },
                          "platformAdAccountName": {
                            "description": "Human-readable advertiser/account name from the platform. Refreshed on every sync.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformCampaignId": {
                            "type": "string"
                          },
                          "platformCampaignStatus": {
                            "description": "Raw platform-level campaign status (Meta `effective_status`: ACTIVE, PAUSED, DELETED, ARCHIVED, IN_PROCESS, WITH_ISSUES; ChatGPT (OpenAI): the campaign's own switch, active / paused / archived, independent of the delivery `status`; TikTok…",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "platformObjective": {
                            "description": "Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC)",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "previousMetrics": {
                            "description": "Only with `compare=previous`. The same metrics over `previousRange`.",
                            "properties": {
                              "actionValues": {
                                "additionalProperties": true,
                                "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                "type": "object"
                              },
                              "actions": {
                                "additionalProperties": true,
                                "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                "type": "object"
                              },
                              "allConversions": {
                                "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                "type": "number"
                              },
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                "type": "number"
                              },
                              "costPerAction": {
                                "additionalProperties": true,
                                "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                "type": "object"
                              },
                              "costPerConversion": {
                                "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                "type": "number"
                              },
                              "costPerThruplay": {
                                "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                "type": "number"
                              },
                              "cpc": {
                                "description": "Cost per click",
                                "type": "number"
                              },
                              "cpm": {
                                "description": "Cost per 1000 impressions",
                                "type": "number"
                              },
                              "ctr": {
                                "description": "Click-through rate (%)",
                                "type": "number"
                              },
                              "engagement": {
                                "type": "integer"
                              },
                              "engagementBreakdown": {
                                "additionalProperties": true,
                                "description": "The single `engagement` total, split into the interactions behind it.",
                                "type": "object"
                              },
                              "funnel": {
                                "additionalProperties": true,
                                "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                "type": "object"
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "inlineLinkClickCtr": {
                                "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "inlineLinkClicks": {
                                "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                "type": "integer"
                              },
                              "lastSyncedAt": {
                                "description": "Present on individual ads only, not on campaign aggregations",
                                "format": "date-time",
                                "type": "string"
                              },
                              "outboundClicks": {
                                "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                "type": "integer"
                              },
                              "outboundClicksCtr": {
                                "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "purchaseValue": {
                                "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                "type": "number"
                              },
                              "reach": {
                                "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                "type": "integer"
                              },
                              "roas": {
                                "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                "type": "number"
                              },
                              "spend": {
                                "type": "number"
                              },
                              "uniqueClicks": {
                                "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                "type": "integer"
                              },
                              "uniqueCtr": {
                                "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                "type": "number"
                              },
                              "video2SecWatchedActions": {
                                "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                "type": "integer"
                              },
                              "video30SecWatchedActions": {
                                "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                "type": "integer"
                              },
                              "video6SecFocusedViews": {
                                "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                "type": "integer"
                              },
                              "video6SecWatchedActions": {
                                "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                "type": "integer"
                              },
                              "videoAvgTimeWatchedActions": {
                                "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                "type": "number"
                              },
                              "videoP100WatchedActions": {
                                "description": "Views reaching 100% of the video's length.",
                                "type": "integer"
                              },
                              "videoP25WatchedActions": {
                                "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                "type": "integer"
                              },
                              "videoP50WatchedActions": {
                                "description": "Views reaching 50% of the video's length.",
                                "type": "integer"
                              },
                              "videoP75WatchedActions": {
                                "description": "Views reaching 75% of the video's length.",
                                "type": "integer"
                              },
                              "videoP95WatchedActions": {
                                "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                "type": "integer"
                              },
                              "videoPlayActions": {
                                "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                "type": "integer"
                              },
                              "videoThruplayWatchedActions": {
                                "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "promotedObject": {
                            "description": "Meta promoted object at campaign level (conversion event details)",
                            "properties": {
                              "custom_event_type": {
                                "type": "string"
                              },
                              "page_id": {
                                "type": "string"
                              },
                              "pixel_id": {
                                "type": "string"
                              }
                            },
                            "type": [
                              "object",
                              "null"
                            ]
                          },
                          "results": {
                            "additionalProperties": {
                              "type": "number"
                            },
                            "description": "Only with `results=true`. The values you sent for this campaign over the range, plus each formula they allow, by metric key. A metric with no value is absent.",
                            "type": "object"
                          },
                          "reviewStatus": {
                            "anyOf": [
                              {
                                "description": "Platform-side review state, independent of the delivery `status` and the `configuredStatus` on/off toggle. `in_review` means the platform is still reviewing. Absent when the platform reports no review signal (e.g.",
                                "enum": [
                                  "in_review",
                                  "approved",
                                  "rejected",
                                  "with_issues"
                                ],
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Platform-side review state of the campaign."
                          },
                          "roasAverageFloor": {
                            "description": "Representative ROAS floor for the campaign, bubbled up from the top-spending ad set. Decimal multiplier (2.0 = 2.0x).",
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "status": {
                            "description": "Delivery status derived from child ad statuses. Distinct from `reviewStatus`, which reflects the platform-side review state.",
                            "enum": [
                              "active",
                              "paused",
                              "pending_review",
                              "rejected",
                              "completed",
                              "cancelled",
                              "error"
                            ],
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "pagination": {
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "pages": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      },
                      "type": "object"
                    },
                    "previousRange": {
                      "description": "Only with `compare=previous`. The range `previousMetrics` covers.",
                      "properties": {
                        "fromDate": {
                          "format": "date",
                          "type": "string"
                        },
                        "toDate": {
                          "format": "date",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "syncedAt": {
                      "description": "When the most recently synced ad on this page was last read from the platform. Null before the first sync.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "backfillPending"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Meta only. Historical data is incomplete and backfill remains pending."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get campaign tree",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_tree@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "ae8bd1f34736d5f38973959b1898d2eef829c17e7a5fbf90599f80fce7d8c040"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_tree",
          "method": "GET",
          "path": "/apis/v1/ads/tree"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_tree"
      }
    },
    "/apis/v1/ads/value-rule-sets": {
      "get": {
        "description": "Ad Accounts. Read only. Lists a Meta ad account's value rule sets, which raise or lower bids for audience segments you value differently. Lists the ad account's value rule sets (Meta's `/act_X/value_rule_set`). A value rule set adjusts the auction bid up or down for audience segments you value differently; attach one to an ad set with `valueRuleSetId` on `POST /apis/v1/ads/create` or `PUT /apis/v1/ads/ad-sets/{adSetId}`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_value_rule_sets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Rows per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from paging.after of the previous page. Meta does not document paging on this edge; `after` comes back null when it omits cursors.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "description": "A named set of bid-adjustment rules on an ad account. Attach it to an ad set with `valueRuleSetId`. Limits: 6 sets per ad account, 10 rules per set, 4 criteria per rule.",
                        "properties": {
                          "id": {
                            "description": "Platform value rule set id.",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "rules": {
                            "description": "Evaluated in order; the first matching rule wins.",
                            "items": {
                              "additionalProperties": true,
                              "description": "One bid-adjustment rule. Rules are evaluated in ARRAY ORDER and only the first matching rule adjusts the bid for an overlapping audience, so the order is semantic.",
                              "type": "object"
                            },
                            "type": "array"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "rules"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted or when Meta omits paging.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Value rule sets"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List value rule sets",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_value_rule_sets@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "397466da23f006d2d0f3045de74cf5e07d97cf78f9f3e8513b9c4ff92dc318c5"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_value_rule_sets",
          "method": "GET",
          "path": "/apis/v1/ads/value-rule-sets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_value_rule_sets"
      },
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Creates a Meta value rule set that raises or lowers bids for chosen audience segments, ready to attach to ad sets. Creates a value rule set on the ad account (Meta's `POST /act_X/value_rule_set`). Attach the returned id to an ad set with `valueRuleSetId` on `POST /apis/v1/ads/create` or `PUT /apis/v1/ads/ad-sets/{adSetId}`. ### Rule order is semantic\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_value_rule_sets",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch",
                "rules": [
                  {
                    "adjustSign": "INCREASE",
                    "adjustValue": 10,
                    "criteria": [
                      {
                        "criteriaType": "AGE",
                        "criteriaValueTypes": [
                          "example"
                        ],
                        "criteriaValues": [
                          "example"
                        ],
                        "operator": "CONTAINS"
                      }
                    ],
                    "name": "Winter launch"
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account id (Meta act_, Google customer id, LinkedIn account id, ...).",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "name": {
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "rules": {
                    "description": "Evaluated in order; the first matching rule wins.",
                    "items": {
                      "additionalProperties": false,
                      "description": "One bid-adjustment rule. Rules are evaluated in ARRAY ORDER and only the first matching rule adjusts the bid for an overlapping audience, so the order is semantic.",
                      "properties": {
                        "adjustSign": {
                          "description": "Direction of the adjustment. There is no signed value field.",
                          "enum": [
                            "INCREASE",
                            "DECREASE"
                          ],
                          "type": "string"
                        },
                        "adjustValue": {
                          "description": "Unsigned percentage magnitude. `INCREASE` accepts 1-1000, `DECREASE` accepts 1-90. 0 is out of range on both.",
                          "maximum": 1000,
                          "minimum": 1,
                          "type": "integer"
                        },
                        "criteria": {
                          "description": "All criteria on a rule must match for the rule to fire.",
                          "items": {
                            "additionalProperties": false,
                            "description": "One matching condition inside a value rule. `criteriaValues` and `criteriaValueTypes` are POSITIONALLY paired: same length, same order.",
                            "properties": {
                              "criteriaType": {
                                "description": "The dimension being matched. `OMNI_CHANNEL` (conversion location: APP, INSTANT_FORM, PHONE_CALL, WEBSITE) is accepted even though Meta's own enum table omits it.",
                                "enum": [
                                  "AGE",
                                  "GENDER",
                                  "OS_TYPE",
                                  "DEVICE_PLATFORM",
                                  "LOCATION",
                                  "PLACEMENT",
                                  "OMNI_CHANNEL",
                                  "AUDIENCE_LABEL"
                                ],
                                "type": "string"
                              },
                              "criteriaValueTypes": {
                                "description": "One entry per `criteriaValues` entry, in the same order.",
                                "items": {
                                  "type": "string"
                                },
                                "minItems": 1,
                                "type": "array"
                              },
                              "criteriaValues": {
                                "description": "The values to match. `AGE`: ranges such as `18-24`, `18+` or a custom `18-26`. A range whose upper bound is 65 is NOT allowed (use `18+` instead of `18-65`). `LOCATION`: Targeting-Search keys.",
                                "items": {
                                  "type": "string"
                                },
                                "minItems": 1,
                                "type": "array"
                              },
                              "id": {
                                "description": "Platform criterion id. Echo it on `PUT` to KEEP this criterion, omit it to CREATE a new one. A criterion left out of the array entirely is DELETED.",
                                "type": "string"
                              },
                              "operator": {
                                "description": "Required on every criterion. `CONTAINS` is currently the only value Meta supports.",
                                "enum": [
                                  "CONTAINS"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "criteriaType",
                              "criteriaValueTypes",
                              "criteriaValues",
                              "operator"
                            ],
                            "type": "object"
                          },
                          "maxItems": 4,
                          "minItems": 1,
                          "type": "array"
                        },
                        "id": {
                          "description": "Platform rule id. Echo it on `PUT` to KEEP this rule, omit it to CREATE a new one. A rule left out of the array entirely is DELETED.",
                          "type": "string"
                        },
                        "name": {
                          "maxLength": 255,
                          "minLength": 1,
                          "type": "string"
                        },
                        "status": {
                          "description": "Meta returns `ACTIVE` here but documents no enum for the field. Treat it as a passthrough: echo whatever the `GET` returned, and do not synthesize values.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "adjustSign",
                        "adjustValue",
                        "criteria",
                        "name"
                      ],
                      "type": "object"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "adAccountId",
                  "name",
                  "rules"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "valueRuleSetId": {
                      "description": "The new rule set id. Meta does not document the create response body, so this is null on the (unobserved) case where it omits the id.",
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Value rule set created"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Create a value rule set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.create_value_rule_set@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "3b09590a94c5bdf450b9cd64dd5d66ddd1d66ef6a38bfcc9fcc6e537b526c319"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_value_rule_sets",
          "method": "POST",
          "path": "/apis/v1/ads/value-rule-sets"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_value_rule_sets"
      }
    },
    "/apis/v1/ads/value-rule-sets/{valueRuleSetId}": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Deletes a Meta value rule set (detach it from ad sets first, since they are not changed here). Deletes the rule set (Meta's `POST /{value-rule-set-id}/delete_rule_set`, a custom action edge rather than an HTTP DELETE on its side). Ad sets pointing at it are not modified here; detach them first with `valueRulesApplied: false` on `PUT /apis/v1/ads/ad-sets/{adSetId}`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_value_rule_sets_value_0c2d11",
        "parameters": [
          {
            "description": "Platform value rule set id.",
            "in": "path",
            "name": "valueRuleSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "valueRuleSetId": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Value rule set deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete a value rule set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_value_rule_set@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "1c805b05d22ef55acc9b46af35d8406e59ab641a977fee6b91c5fdd5de1b8e37"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_value_rule_sets_value_0c2d11",
          "method": "DELETE",
          "path": "/apis/v1/ads/value-rule-sets/{valueRuleSetId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_value_rule_sets_value_0c2d11"
      },
      "get": {
        "description": "Ad Accounts. Read only. Shows one Meta value rule set with all its rules and criteria, the first step before editing it. Reads one value rule set including every nested rule id and criterion id. This is step one of any edit: `PUT` is a full replace, so you need the ids before you can keep the objects you are not changing. Meta's own read returns `GENDER` values lowercase (`\"male\"`) while writes require `\"MALE\"`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_value_rule_sets_valuerulesetid",
        "parameters": [
          {
            "description": "Platform value rule set id.",
            "in": "path",
            "name": "valueRuleSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "valueRuleSet": {
                      "description": "A named set of bid-adjustment rules on an ad account. Attach it to an ad set with `valueRuleSetId`. Limits: 6 sets per ad account, 10 rules per set, 4 criteria per rule.",
                      "properties": {
                        "id": {
                          "description": "Platform value rule set id.",
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "rules": {
                          "description": "Evaluated in order; the first matching rule wins.",
                          "items": {
                            "description": "One bid-adjustment rule. Rules are evaluated in ARRAY ORDER and only the first matching rule adjusts the bid for an overlapping audience, so the order is semantic.",
                            "properties": {
                              "adjustSign": {
                                "description": "Direction of the adjustment. There is no signed value field.",
                                "enum": [
                                  "INCREASE",
                                  "DECREASE"
                                ],
                                "type": "string"
                              },
                              "adjustValue": {
                                "description": "Unsigned percentage magnitude. `INCREASE` accepts 1-1000, `DECREASE` accepts 1-90. 0 is out of range on both.",
                                "maximum": 1000,
                                "minimum": 1,
                                "type": "integer"
                              },
                              "criteria": {
                                "description": "All criteria on a rule must match for the rule to fire.",
                                "items": {
                                  "additionalProperties": true,
                                  "description": "One matching condition inside a value rule. `criteriaValues` and `criteriaValueTypes` are POSITIONALLY paired: same length, same order.",
                                  "type": "object"
                                },
                                "maxItems": 4,
                                "minItems": 1,
                                "type": "array"
                              },
                              "id": {
                                "description": "Platform rule id. Echo it on `PUT` to KEEP this rule, omit it to CREATE a new one. A rule left out of the array entirely is DELETED.",
                                "type": "string"
                              },
                              "name": {
                                "maxLength": 255,
                                "minLength": 1,
                                "type": "string"
                              },
                              "status": {
                                "description": "Meta returns `ACTIVE` here but documents no enum for the field. Treat it as a passthrough: echo whatever the `GET` returned, and do not synthesize values.",
                                "type": "string"
                              }
                            },
                            "required": [
                              "adjustSign",
                              "adjustValue",
                              "criteria",
                              "name"
                            ],
                            "type": "object"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "rules"
                      ],
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Value rule set"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Read a value rule set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_value_rule_set@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "af2c45330f327e6857064822a30e0757c09606e95e8c2370f692b1aac5f19d21"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_value_rule_sets_valuerulesetid",
          "method": "GET",
          "path": "/apis/v1/ads/value-rule-sets/{valueRuleSetId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_value_rule_sets_valuerulesetid"
      },
      "put": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Replaces a Meta value rule set with the rules you send, so any rule left out is deleted. THIS IS A FULL REPLACE, NOT A PATCH. Meta's update is declarative: the body you send becomes the rule set. `GET /apis/v1/ads/value-rule-sets/{valueRuleSetId}` FIRST. Keep a rule or criterion by echoing its `id`. Create one by including the object WITHOUT an `id`. Delete one by OMITTING it from the array.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_value_rule_sets_valuerulesetid",
        "parameters": [
          {
            "description": "Platform value rule set id.",
            "in": "path",
            "name": "valueRuleSetId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "name": "Winter launch",
                "rules": [
                  {
                    "adjustSign": "INCREASE",
                    "adjustValue": 10,
                    "criteria": [
                      {
                        "criteriaType": "AGE",
                        "criteriaValueTypes": [
                          "example"
                        ],
                        "criteriaValues": [
                          "example"
                        ],
                        "operator": "CONTAINS"
                      }
                    ],
                    "name": "Winter launch"
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "name": {
                    "description": "Required: the update replaces the whole set.",
                    "maxLength": 255,
                    "minLength": 1,
                    "type": "string"
                  },
                  "rules": {
                    "description": "The COMPLETE rule list. Omitting a rule deletes it on Meta.",
                    "items": {
                      "additionalProperties": false,
                      "description": "One bid-adjustment rule. Rules are evaluated in ARRAY ORDER and only the first matching rule adjusts the bid for an overlapping audience, so the order is semantic.",
                      "properties": {
                        "adjustSign": {
                          "description": "Direction of the adjustment. There is no signed value field.",
                          "enum": [
                            "INCREASE",
                            "DECREASE"
                          ],
                          "type": "string"
                        },
                        "adjustValue": {
                          "description": "Unsigned percentage magnitude. `INCREASE` accepts 1-1000, `DECREASE` accepts 1-90. 0 is out of range on both.",
                          "maximum": 1000,
                          "minimum": 1,
                          "type": "integer"
                        },
                        "criteria": {
                          "description": "All criteria on a rule must match for the rule to fire.",
                          "items": {
                            "additionalProperties": false,
                            "description": "One matching condition inside a value rule. `criteriaValues` and `criteriaValueTypes` are POSITIONALLY paired: same length, same order.",
                            "properties": {
                              "criteriaType": {
                                "description": "The dimension being matched. `OMNI_CHANNEL` (conversion location: APP, INSTANT_FORM, PHONE_CALL, WEBSITE) is accepted even though Meta's own enum table omits it.",
                                "enum": [
                                  "AGE",
                                  "GENDER",
                                  "OS_TYPE",
                                  "DEVICE_PLATFORM",
                                  "LOCATION",
                                  "PLACEMENT",
                                  "OMNI_CHANNEL",
                                  "AUDIENCE_LABEL"
                                ],
                                "type": "string"
                              },
                              "criteriaValueTypes": {
                                "description": "One entry per `criteriaValues` entry, in the same order.",
                                "items": {
                                  "type": "string"
                                },
                                "minItems": 1,
                                "type": "array"
                              },
                              "criteriaValues": {
                                "description": "The values to match. `AGE`: ranges such as `18-24`, `18+` or a custom `18-26`. A range whose upper bound is 65 is NOT allowed (use `18+` instead of `18-65`). `LOCATION`: Targeting-Search keys.",
                                "items": {
                                  "type": "string"
                                },
                                "minItems": 1,
                                "type": "array"
                              },
                              "id": {
                                "description": "Platform criterion id. Echo it on `PUT` to KEEP this criterion, omit it to CREATE a new one. A criterion left out of the array entirely is DELETED.",
                                "type": "string"
                              },
                              "operator": {
                                "description": "Required on every criterion. `CONTAINS` is currently the only value Meta supports.",
                                "enum": [
                                  "CONTAINS"
                                ],
                                "type": "string"
                              }
                            },
                            "required": [
                              "criteriaType",
                              "criteriaValueTypes",
                              "criteriaValues",
                              "operator"
                            ],
                            "type": "object"
                          },
                          "maxItems": 4,
                          "minItems": 1,
                          "type": "array"
                        },
                        "id": {
                          "description": "Platform rule id. Echo it on `PUT` to KEEP this rule, omit it to CREATE a new one. A rule left out of the array entirely is DELETED.",
                          "type": "string"
                        },
                        "name": {
                          "maxLength": 255,
                          "minLength": 1,
                          "type": "string"
                        },
                        "status": {
                          "description": "Meta returns `ACTIVE` here but documents no enum for the field. Treat it as a passthrough: echo whatever the `GET` returned, and do not synthesize values.",
                          "type": "string"
                        }
                      },
                      "required": [
                        "adjustSign",
                        "adjustValue",
                        "criteria",
                        "name"
                      ],
                      "type": "object"
                    },
                    "maxItems": 10,
                    "minItems": 1,
                    "type": "array"
                  }
                },
                "required": [
                  "name",
                  "rules"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "rules": {
                      "items": {
                        "description": "One bid-adjustment rule. Rules are evaluated in ARRAY ORDER and only the first matching rule adjusts the bid for an overlapping audience, so the order is semantic.",
                        "properties": {
                          "adjustSign": {
                            "description": "Direction of the adjustment. There is no signed value field.",
                            "enum": [
                              "INCREASE",
                              "DECREASE"
                            ],
                            "type": "string"
                          },
                          "adjustValue": {
                            "description": "Unsigned percentage magnitude. `INCREASE` accepts 1-1000, `DECREASE` accepts 1-90. 0 is out of range on both.",
                            "maximum": 1000,
                            "minimum": 1,
                            "type": "integer"
                          },
                          "criteria": {
                            "description": "All criteria on a rule must match for the rule to fire.",
                            "items": {
                              "additionalProperties": true,
                              "description": "One matching condition inside a value rule. `criteriaValues` and `criteriaValueTypes` are POSITIONALLY paired: same length, same order.",
                              "type": "object"
                            },
                            "maxItems": 4,
                            "minItems": 1,
                            "type": "array"
                          },
                          "id": {
                            "description": "Platform rule id. Echo it on `PUT` to KEEP this rule, omit it to CREATE a new one. A rule left out of the array entirely is DELETED.",
                            "type": "string"
                          },
                          "name": {
                            "maxLength": 255,
                            "minLength": 1,
                            "type": "string"
                          },
                          "status": {
                            "description": "Meta returns `ACTIVE` here but documents no enum for the field. Treat it as a passthrough: echo whatever the `GET` returned, and do not synthesize values.",
                            "type": "string"
                          }
                        },
                        "required": [
                          "adjustSign",
                          "adjustValue",
                          "criteria",
                          "name"
                        ],
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "valueRuleSetId": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Value rule set replaced"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Replace a value rule set",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_value_rule_set@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "c5c051944fc597a8e2a1a7e8df65e69902925ac4c7b1927849ba6d5f0e0ea225"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_value_rule_sets_valuerulesetid",
          "method": "PUT",
          "path": "/apis/v1/ads/value-rule-sets/{valueRuleSetId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_value_rule_sets_valuerulesetid"
      }
    },
    "/apis/v1/ads/videos": {
      "get": {
        "description": "Ad Creatives. Read only. Lists the videos in a Meta ad account's library, including ones uploaded elsewhere, so you can reuse one across ads. It lists the ad account's video library (Meta's `/act_X/advideos`), rows returned verbatim. The default projection covers id, title, status, poster frames, length and `source` (the playable MP4). `fields` is a raw-passthrough override.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_videos",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_).",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Graph field override.",
            "in": "query",
            "name": "fields",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Rows per page",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Cursor from paging.after of the previous page.",
            "in": "query",
            "name": "after",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "data": {
                      "items": {
                        "description": "Raw Meta ad video row (id, title, status, picture, thumbnails, length, source).",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "paging": {
                      "properties": {
                        "after": {
                          "description": "Cursor for the next page; null when exhausted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad videos (raw Meta shape)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Ad video library",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.list_ad_videos@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "183a2ea982d7047ec97fa8828933aff74947e1312cb0c1f6dee12a9b6b0321db"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_videos",
          "method": "GET",
          "path": "/apis/v1/ads/videos"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_videos"
      },
      "post": {
        "description": "Ad Creatives. Changes the ad account without starting or raising spend; audited. Uploads a video to a Meta ad account from a URL or file, so you can preview it or use it in ads before any ad exists. This is a standalone ad-video upload (parallel to POST /apis/v1/ads/images). A video creative can then be rendered via POST /apis/v1/ads/preview or attached via `video.id` on POST /apis/v1/ads/create before an ad exists. ### Input Exactly one is required:\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_videos",
        "parameters": [
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adAccountId": "act_1234567890",
                "connectionId": "adc_7f3k2m9q"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adAccountId": {
                    "description": "Platform ad account id (Meta act_, Google customer id, LinkedIn account id, ...).",
                    "type": "string"
                  },
                  "async": {
                    "default": false,
                    "description": "true: answer 202 once Meta accepts the upload instead of waiting for processing. Poll GET /apis/v1/ads/videos/{videoId} or subscribe to ad.video.processed.",
                    "type": "boolean"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "filename": {
                    "description": "Optional file name, sent to Meta as the video's name and title so it shows and is searchable in the Ads Manager media library. Applies to both videoUrl and videoBase64.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "name": {
                    "description": "Optional video name shown in the Ads Manager media library. Takes precedence over filename.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "videoBase64": {
                    "description": "Raw base64 video bytes, or a full data URL (the data:video/...;base64, prefix is stripped). Capped by Vercel's body limit (~4.5 MB payload). Provide exactly one of videoUrl or videoBase64.",
                    "type": "string"
                  },
                  "videoUrl": {
                    "description": "Public https URL of the video; downloaded server-side (SSRF-guarded) before chunked upload. Provide exactly one of videoUrl or videoBase64.",
                    "type": "string"
                  }
                },
                "required": [
                  "adAccountId"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "video": {
                      "properties": {
                        "id": {
                          "description": "Meta video id, reusable as video.id on POST /apis/v1/ads/create and inside POST /apis/v1/ads/preview creativeSpec.",
                          "type": "string"
                        },
                        "status": {
                          "enum": [
                            "ready"
                          ],
                          "type": "string"
                        },
                        "thumbnailUrl": {
                          "description": "Meta-hosted poster URL if available; null when Meta has not produced a poster yet.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Video uploaded and ready"
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "video": {
                      "properties": {
                        "id": {
                          "description": "Meta video id. Usable as video.id once GET /apis/v1/ads/videos/{videoId} reports ready.",
                          "type": "string"
                        },
                        "status": {
                          "enum": [
                            "processing"
                          ],
                          "type": "string"
                        },
                        "thumbnailUrl": {
                          "description": "Always null on 202; read it from GET /apis/v1/ads/videos/{videoId} once ready.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "async: true. Meta accepted the upload and is processing it"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Upload an ad video",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.upload_ad_video@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "40d3928fbce7bde830e8e87e0262cb65ae76e15d6bca0ecdfeb4c2969a3507cb"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_videos",
          "method": "POST",
          "path": "/apis/v1/ads/videos"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_videos"
      }
    },
    "/apis/v1/ads/videos/{videoId}": {
      "delete": {
        "description": "Ad Creatives. Changes the ad account without starting or raising spend; audited. Removes a video from a Meta ad account's video library. Meta's canonical `DELETE /{video_id}` fails with code 10 / subcode 1363055 for videos uploaded via `/act_X/advideos`, even with `ads_management`. This endpoint uses the working account-scoped shape `DELETE /act_X/advideos?video_id=` and returns Meta's `{success: true}` verbatim.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_videos_videoid",
        "parameters": [
          {
            "description": "Meta ad video id (numeric).",
            "in": "path",
            "name": "videoId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_) that owns the video.",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "success": {
                      "type": "boolean"
                    },
                    "videoId": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Video deleted"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete an ad video",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_video@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "344dba71503b5eadfc03bb9ff69c2af0f6a5a3fbf3c2271de232c83133141a3b"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_videos_videoid",
          "method": "DELETE",
          "path": "/apis/v1/ads/videos/{videoId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_videos_videoid"
      },
      "get": {
        "description": "Ad Creatives. Read only. Checks whether an uploaded Meta ad video has finished processing and is ready to use in an ad. Reads a video's processing state live from Meta (`GET /{video-id}?fields=status`). Poll this after `POST /apis/v1/ads/videos` with `async: true` until `status` is `ready`; the video is only usable as `video.id` on the create endpoints from then on.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_videos_videoid",
        "parameters": [
          {
            "description": "Meta ad video id (numeric).",
            "in": "path",
            "name": "videoId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Meta ad account id (act_) the video was uploaded to.",
            "in": "query",
            "name": "adAccountId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adAccountId": {
                      "type": "string"
                    },
                    "video": {
                      "properties": {
                        "error": {
                          "description": "Meta's processing error when status is error.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "platformStatus": {
                          "description": "Meta's raw status.video_status, forwarded verbatim.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "processingProgress": {
                          "description": "Meta's processing percentage when reported.",
                          "maximum": 100,
                          "minimum": 0,
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "status": {
                          "enum": [
                            "processing",
                            "ready",
                            "error"
                          ],
                          "type": "string"
                        },
                        "thumbnailUrl": {
                          "description": "Meta's auto-generated poster once ready, when Meta produced one.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "error",
                        "id",
                        "platformStatus",
                        "processingProgress",
                        "status",
                        "thumbnailUrl"
                      ],
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Processing status"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get ad video processing status",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_video_status@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "ebddf710d0e354bb3660f5223076432a30e779b0a37c2db555bd4f7a219392fb"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_videos_videoid",
          "method": "GET",
          "path": "/apis/v1/ads/videos/{videoId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_videos_videoid"
      }
    },
    "/apis/v1/ads/{adId}": {
      "delete": {
        "description": "Ad Campaigns. Changes the ad account without starting or raising spend; audited. Deletes an ad on the platform while keeping its history, and removes empty parents only when they were created through this API. The ad is deleted on the platform and marked as cancelled in the database. It is preserved for history. OpenAI Ads has no delete API: the ad is archived instead (a terminal state, the closest equivalent).\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_adid",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad cancelled"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Cancel an ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0cb7212bf5e926eec73460433a08dd3bc166b9ee2cb09b8c05835ee5eab71549"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_adid",
          "method": "DELETE",
          "path": "/apis/v1/ads/{adId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_adid"
      },
      "get": {
        "description": "Ad Campaigns. Read only. Shows one ad with its creative, targeting, status and performance metrics. ### Google Search ads Google Search ads include current creative.headlines, creative.descriptions and creative.finalUrls, preserving pinnedField. Top-level cachedAt and stale report cache freshness. Google mutations invalidate this read. RSA enrichment requires a stored advertisingChannelType of SEARCH.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_adid",
        "parameters": [
          {
            "description": "See description for details.",
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Read the on/off switches live from the platform instead of returning synced values. See \"Status freshness\" in the operation description.",
            "in": "query",
            "name": "live",
            "required": false,
            "schema": {
              "default": false,
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ad": {
                      "properties": {
                        "_id": {
                          "type": "string"
                        },
                        "adSetName": {
                          "type": "string"
                        },
                        "adType": {
                          "enum": [
                            "boost",
                            "standalone"
                          ],
                          "type": "string"
                        },
                        "bidAmount": {
                          "description": "Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). Meta: `bid_amount` on the ad set (smallest-denomination int, decoded here).",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "bidStrategy": {
                          "anyOf": [
                            {
                              "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                              "enum": [
                                "LOWEST_COST_WITHOUT_CAP",
                                "LOWEST_COST_WITH_BID_CAP",
                                "COST_CAP",
                                "LOWEST_COST_WITH_MIN_ROAS"
                              ],
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Ad-set bid strategy (overrides campaign level on Meta). Populated for Meta and TikTok."
                        },
                        "budget": {
                          "properties": {
                            "amount": {
                              "type": "number"
                            },
                            "daily": {
                              "description": "LinkedIn and X only. The daily budget (LinkedIn: the parent campaign's `dailyBudget`; X: the line item's, or the campaign's when the line item has none).",
                              "type": "number"
                            },
                            "lifetime": {
                              "description": "LinkedIn and X only. The lifetime total (LinkedIn: the parent campaign's `totalBudget`; X: `total_budget_amount_local_micro`, for example the `lifetimeBudgetCap` of a boost), readable even when a daily budget is also set.",
                              "type": "number"
                            },
                            "pacing": {
                              "description": "LinkedIn only. The campaign's `pacingStrategy`: how fast LinkedIn may spend the budget. Typically LINEAR or ACCELERATED; the list is open.",
                              "type": "string"
                            },
                            "type": {
                              "enum": [
                                "daily",
                                "lifetime"
                              ],
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "campaignName": {
                          "type": "string"
                        },
                        "configuredStatus": {
                          "description": "The ad's own on/off switch as configured on the platform, independent of its parents. An ACTIVE ad under a paused ad set or campaign still reads ACTIVE here while `status` reads `paused`. Sources: Meta: `configured_status`.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "costType": {
                          "description": "LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn, refreshed on every sync rather than echoing what was passed on create. `null` for non-LinkedIn ads. `CPM`: cost per thousand impressions.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "createdAt": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "creative": {
                          "description": "Platform-specific creative data. Fields vary by platform.",
                          "properties": {
                            "adFormat": {
                              "description": "LinkedIn only. The LinkedIn ad format, in LinkedIn's own vocabulary: STANDARD_UPDATE, SINGLE_VIDEO, CAROUSEL, NATIVE_DOCUMENT, EVENT, TEXT_AD, SPOTLIGHT, FOLLOW_COMPANY, JOBS, SPONSORED_INMAILS and others.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "assetGroup": {
                              "description": "Google Performance Max creative assets. At least one description must be 60 characters or fewer. Texts within each list must be distinct.",
                              "properties": {
                                "businessName": {
                                  "maxLength": 25,
                                  "minLength": 1,
                                  "type": "string"
                                },
                                "descriptions": {
                                  "description": "At least one description must be 60 characters or fewer.",
                                  "items": {
                                    "maxLength": 90,
                                    "minLength": 1,
                                    "type": "string"
                                  },
                                  "maxItems": 5,
                                  "minItems": 2,
                                  "type": "array",
                                  "uniqueItems": true
                                },
                                "finalUrl": {
                                  "description": "Required destination URL.",
                                  "format": "uri",
                                  "pattern": "^https?://",
                                  "type": "string"
                                },
                                "headlines": {
                                  "items": {
                                    "maxLength": 30,
                                    "minLength": 1,
                                    "type": "string"
                                  },
                                  "maxItems": 15,
                                  "minItems": 3,
                                  "type": "array",
                                  "uniqueItems": true
                                },
                                "images": {
                                  "additionalProperties": true,
                                  "description": "Public HTTP(S) image URLs. GIF, JPEG or PNG, at most 5120 KB per image. Google validates dimensions and aspect ratios.",
                                  "type": "object"
                                },
                                "longHeadline": {
                                  "maxLength": 90,
                                  "minLength": 1,
                                  "type": "string"
                                },
                                "name": {
                                  "description": "Defaults to the request name.",
                                  "maxLength": 128,
                                  "minLength": 1,
                                  "type": "string"
                                },
                                "youtubeVideoId": {
                                  "description": "Optional existing YouTube video id. Google can generate video when omitted. Video uploads and arbitrary video URLs are not supported.",
                                  "pattern": "^[A-Za-z0-9_-]{11}$",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "businessName",
                                "descriptions",
                                "finalUrl",
                                "headlines",
                                "images",
                                "longHeadline"
                              ],
                              "type": "object"
                            },
                            "assetGroupResourceName": {
                              "description": "Google resource name of the created Performance Max asset group.",
                              "type": "string"
                            },
                            "assetResourceName": {
                              "description": "Google Display only. Resource name of the landscape marketing image asset (`creative.imageUrl`), for example customers/1234567890/assets/123.",
                              "type": "string"
                            },
                            "assets": {
                              "description": "Google Display only. Native Google asset resource name of each image on the responsive display ad, keyed by Google's image role.",
                              "properties": {
                                "marketingImages": {
                                  "description": "Landscape (1.91:1) marketing images. The first item matches `assetResourceName`.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "squareMarketingImages": {
                                  "description": "Square (1:1) marketing images.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "bodies": {
                              "description": "Meta: every primary text variation of the creative (`asset_feed_spec.bodies`), the same shape as the `bodies` create input. Present only with 2 or more texts; a single text is `body`.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "body": {
                              "description": "Ad copy/text",
                              "type": "string"
                            },
                            "callToAction": {
                              "description": "Meta: the call to action type (`call_to_action.type`, or the first `asset_feed_spec.call_to_action_types` entry), e.g. LEARN_MORE or SIGN_UP.",
                              "type": "string"
                            },
                            "carouselCards": {
                              "description": "Meta only today. The carousel's cards in display order, one per Meta `link_data.child_attachments` entry, using the same field names as the `carouselCards` create input. Absent on non-carousel ads and other platforms.",
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "type": "array"
                            },
                            "catalog": {
                              "properties": {
                                "format": {
                                  "description": "object_story_spec.template_data.format_option, from catalogFormat.",
                                  "enum": [
                                    "single_image",
                                    "carousel_images_multi_items",
                                    "carousel_images_single_item",
                                    "carousel_slideshows"
                                  ],
                                  "type": "string"
                                },
                                "formatTransformationSpec": {
                                  "description": "The format_transformation_spec sent on the creative, as Meta's raw objects. Present for single_image.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "productSetId": {
                                  "description": "The creative's product_set_id.",
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "creativeFeatures": {
                              "additionalProperties": {
                                "enum": [
                                  "OPT_IN",
                                  "OPT_OUT"
                                ],
                                "type": "string"
                              },
                              "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                              "type": "object"
                            },
                            "creativeId": {
                              "description": "Meta ad creative id backing this ad, refreshed from Meta on every sync. Reusable via existingCreativeId on POST /apis/v1/ads/create, and readable raw through GET /apis/v1/ads/creatives/{creativeId}.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "description": {
                              "description": "Meta: the creative's description under the title (`link_data.description`, `video_data.link_description`, or the first `asset_feed_spec.descriptions` entry).",
                              "type": "string"
                            },
                            "descriptions": {
                              "description": "Google RSA: the description assets as objects (2 to 4). Meta: every description variation of the creative (`asset_feed_spec.descriptions`) as strings, the same shape as the `descriptions` create input.",
                              "items": {
                                "oneOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "additionalProperties": true,
                                    "type": "object"
                                  }
                                ]
                              },
                              "maxItems": 4,
                              "type": "array"
                            },
                            "effectiveInstagramMediaId": {
                              "description": "Meta `effective_instagram_media_id`, the Instagram media ID of the boosted post the ad's engagement lives on. Pass to GET /apis/v1/ads?effectiveInstagramMediaId= to map a Business-Manager-visible IG post back to this ad.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "effectiveObjectStoryId": {
                              "description": "Meta `effective_object_story_id`, the `{pageId}_{postId}` of the Facebook post the ad's engagement (comments) lives on.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "finalUrls": {
                              "description": "Google RSA only. Replaces final URLs. Omitted lists stay unchanged.",
                              "items": {
                                "format": "uri",
                                "type": "string"
                              },
                              "minItems": 1,
                              "type": "array"
                            },
                            "googleDescription": {
                              "description": "Google Ads description",
                              "type": "string"
                            },
                            "googleHeadline": {
                              "description": "Google Ads headline",
                              "type": "string"
                            },
                            "headline": {
                              "description": "Meta: the creative's title (`link_data.name`, `video_data.title`, or the first `asset_feed_spec.titles` entry). Absent when the creative has none.",
                              "type": "string"
                            },
                            "headlines": {
                              "description": "Google RSA: the headline assets as objects (3 to 15). Meta: every title variation of the creative (`asset_feed_spec.titles`) as strings, the same shape as the `headlines` create input.",
                              "items": {
                                "oneOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "additionalProperties": true,
                                    "type": "object"
                                  }
                                ]
                              },
                              "maxItems": 15,
                              "type": "array"
                            },
                            "imageHash": {
                              "description": "Meta: the ad image hash (`image_hash`), reusable as `imageHash` on POST /apis/v1/ads/create within the same ad account. `thumbnailUrl` and `mediaUrls` carry its stable full resolution permalink when Meta resolves it.",
                              "type": "string"
                            },
                            "imageUrl": {
                              "description": "Alternative image URL",
                              "type": "string"
                            },
                            "instagramPermalinkUrl": {
                              "description": "Meta `instagram_permalink_url`, the public Instagram post URL of the boosted media.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "instagramUserId": {
                              "description": "Meta `instagram_user_id`, the Instagram-scoped business ID that owns the boosted media.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "instagramVideoFallback": {
                              "description": "Meta only. `instagram_video_reuploaded`: the video was copied into the ad account, and the ad still references the original post.",
                              "properties": {
                                "kind": {
                                  "enum": [
                                    "instagram_video_reuploaded",
                                    "instagram_video_rehosted_copy"
                                  ],
                                  "type": "string"
                                },
                                "linkedToOriginalPost": {
                                  "description": "True when the ad still references the original Instagram post and keeps its engagement.",
                                  "type": "boolean"
                                },
                                "platformError": {
                                  "additionalProperties": true,
                                  "description": "Meta's original refusal.",
                                  "type": "object"
                                },
                                "videoId": {
                                  "description": "instagram_video_reuploaded: the copy in the ad account video library (possibly one made by an earlier boost of the same media, reused).",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "kind",
                                "linkedToOriginalPost",
                                "platformError",
                                "videoId"
                              ],
                              "type": "object"
                            },
                            "isServing": {
                              "description": "LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign.",
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "leadGenFormId": {
                              "description": "Meta: the instant form the call to action opens (`call_to_action.value.lead_gen_form_id`, or the asset feed's `call_to_actions` on a dynamic creative), the same value as the `leadGenFormId` create input. Absent on ads without a lead form.",
                              "type": "string"
                            },
                            "linkUrl": {
                              "description": "Destination URL",
                              "type": "string"
                            },
                            "mediaUrls": {
                              "description": "All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts).",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "objectStoryId": {
                              "description": "Meta creative `object_story_id` (the SHARE reference). Frequently absent, because Meta omits it for SHARE creatives. Use effectiveObjectStoryId instead.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "objectType": {
                              "description": "Meta creative object_type (e.g. SHARE, VIDEO, PRIVACY_CHECK_FAIL, POST_DELETED). Use this to render state-aware previews: when Meta moderation strips image/video fields, only thumbnailUrl at 64x64 is available.",
                              "type": "string"
                            },
                            "pageId": {
                              "description": "Facebook Page backing the creative (Meta only). What the `pageId` filter on /apis/v1/ads, /apis/v1/ads/campaigns and /apis/v1/ads/tree matches against. Absent for non-Meta ads and rare Meta creatives with no page signal.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "pinterestDescription": {
                              "type": "string"
                            },
                            "pinterestImageUrl": {
                              "type": "string"
                            },
                            "pinterestTitle": {
                              "type": "string"
                            },
                            "servingHoldReasons": {
                              "description": "LinkedIn only. Why this specific creative is not being served. Empty when it is serving.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "thumbnailUrl": {
                              "description": "Primary thumbnail/image URL",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "urlTags": {
                              "description": "Meta: the creative's `url_tags` query string appended to the destination URL.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "videoId": {
                              "description": "Meta video ID for VIDEO-type ads. Null for non-video ads. Callers that need an embeddable MP4 can call GET /{videoId}?fields=source with the page access token.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "videoUrl": {
                              "description": "Null for non-video ads.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "whatsappPhoneNumber": {
                              "description": "Explicit E.164 WhatsApp number supplied when creating a Meta boost or messaging ad. Absent when omitted by the caller or on older records.",
                              "type": "string"
                            },
                            "youtubeVideoIds": {
                              "description": "Google only. YouTube video ids behind a Video campaign ad (video and responsive video ads) or a Demand Gen video ad, same id as `youtubeVideoId` on Performance Max asset groups.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "creativeType": {
                          "description": "Creative format, classified from the media the creative carries. `null` when the creative carries no media to classify. An unsynced creative and a genuine text-only ad are indistinguishable, so neither is guessed at.",
                          "enum": [
                            "carousel",
                            "video",
                            "document",
                            "image",
                            null
                          ],
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "goal": {
                          "description": "Available goals vary by platform:",
                          "enum": [
                            "engagement",
                            "traffic",
                            "awareness",
                            "video_views",
                            "lead_generation",
                            "lead_conversion",
                            "conversions",
                            "app_promotion",
                            "catalog_sales",
                            "page_likes",
                            "page_visits",
                            "job_applicants"
                          ],
                          "type": "string"
                        },
                        "isExternal": {
                          "description": "True for ads synced from platform ad managers",
                          "type": "boolean"
                        },
                        "metrics": {
                          "anyOf": [
                            {
                              "properties": {
                                "actionValues": {
                                  "additionalProperties": {
                                    "type": "number"
                                  },
                                  "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                  "type": "object"
                                },
                                "actions": {
                                  "additionalProperties": {
                                    "type": "integer"
                                  },
                                  "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                  "type": "object"
                                },
                                "allConversions": {
                                  "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                  "type": "number"
                                },
                                "clicks": {
                                  "type": "integer"
                                },
                                "conversions": {
                                  "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                  "type": "number"
                                },
                                "costPerAction": {
                                  "additionalProperties": {
                                    "type": "number"
                                  },
                                  "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                  "type": "object"
                                },
                                "costPerConversion": {
                                  "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                  "type": "number"
                                },
                                "costPerThruplay": {
                                  "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                  "type": "number"
                                },
                                "cpc": {
                                  "description": "Cost per click",
                                  "type": "number"
                                },
                                "cpm": {
                                  "description": "Cost per 1000 impressions",
                                  "type": "number"
                                },
                                "ctr": {
                                  "description": "Click-through rate (%)",
                                  "type": "number"
                                },
                                "engagement": {
                                  "type": "integer"
                                },
                                "engagementBreakdown": {
                                  "description": "The single `engagement` total, split into the interactions behind it.",
                                  "properties": {
                                    "comments": {
                                      "description": "Comments on the ad's post.",
                                      "type": "integer"
                                    },
                                    "linkClicks": {
                                      "description": "Attributed link clicks (`link_click`). This is the attribution-window count, which differs from the in-session count in the sibling `inlineLinkClicks` field.",
                                      "type": "integer"
                                    },
                                    "pageEngagement": {
                                      "description": "Meta's own page-engagement total (`page_engagement`). Meta-only.",
                                      "type": "integer"
                                    },
                                    "pageLikes": {
                                      "description": "New Page likes attributed to the ad (`like`).",
                                      "type": "integer"
                                    },
                                    "postEngagement": {
                                      "description": "Meta's own post-engagement total (`post_engagement`). Meta-only.",
                                      "type": "integer"
                                    },
                                    "reactions": {
                                      "description": "Reactions on the ad's post (`post_reaction`). For TikTok these are its paid likes.",
                                      "type": "integer"
                                    },
                                    "saves": {
                                      "description": "Saves of the ad's post (`onsite_conversion.post_save`).",
                                      "type": "integer"
                                    },
                                    "shares": {
                                      "description": "Shares of the ad's post. Meta reports these under the action type literally named `post`; TikTok under `share`.",
                                      "type": "integer"
                                    },
                                    "videoViews": {
                                      "description": "Video views, from the `video_view` action. Meta counts a 3-second view; LinkedIn's own `videoViews` threshold (2 continuous seconds, or 25% of the video) lands under the same key, so compare across platforms with care.",
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "funnel": {
                                  "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                  "properties": {
                                    "appInstalls": {
                                      "description": "Mobile app installs attributed to the ad.",
                                      "type": "integer"
                                    },
                                    "cartAdds": {
                                      "description": "Adds to cart (Meta `AddToCart` pixel event).",
                                      "type": "integer"
                                    },
                                    "checkoutsInitiated": {
                                      "description": "Checkouts started (Meta `InitiateCheckout` pixel event).",
                                      "type": "integer"
                                    },
                                    "contentViews": {
                                      "description": "Content views (Meta `ViewContent` pixel event).",
                                      "type": "integer"
                                    },
                                    "landingPageViews": {
                                      "description": "Landing page views: the visitor actually loaded the destination, unlike a link click. Meta `landing_page_view`.",
                                      "type": "integer"
                                    },
                                    "leads": {
                                      "description": "Leads, from either the website pixel or an instant form, whichever the ad uses.",
                                      "type": "integer"
                                    },
                                    "messagingConversationsStarted": {
                                      "description": "Messaging conversations started within 7 days, the headline metric for click-to-WhatsApp and click-to-Messenger ads.",
                                      "type": "integer"
                                    },
                                    "messagingFirstReplies": {
                                      "description": "Messaging threads where the person sent a first reply.",
                                      "type": "integer"
                                    },
                                    "paymentInfoAdds": {
                                      "description": "Payment details added at checkout (Meta `AddPaymentInfo` pixel event).",
                                      "type": "integer"
                                    },
                                    "purchases": {
                                      "description": "Purchases. Pair with `purchaseValue` for revenue.",
                                      "type": "integer"
                                    },
                                    "registrationsCompleted": {
                                      "description": "Completed registrations (Meta `CompleteRegistration` pixel event).",
                                      "type": "integer"
                                    },
                                    "searches": {
                                      "description": "On-site searches (Meta `Search` pixel event).",
                                      "type": "integer"
                                    },
                                    "wishlistAdds": {
                                      "description": "Adds to wishlist (Meta `AddToWishlist` pixel event).",
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "impressions": {
                                  "type": "integer"
                                },
                                "inlineLinkClickCtr": {
                                  "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                  "type": "number"
                                },
                                "inlineLinkClicks": {
                                  "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                  "type": "integer"
                                },
                                "lastSyncedAt": {
                                  "description": "Present on individual ads only, not on campaign aggregations",
                                  "format": "date-time",
                                  "type": "string"
                                },
                                "outboundClicks": {
                                  "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                  "type": "integer"
                                },
                                "outboundClicksCtr": {
                                  "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                  "type": "number"
                                },
                                "purchaseValue": {
                                  "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                  "type": "number"
                                },
                                "reach": {
                                  "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                  "type": "integer"
                                },
                                "roas": {
                                  "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                  "type": "number"
                                },
                                "spend": {
                                  "type": "number"
                                },
                                "uniqueClicks": {
                                  "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                  "type": "integer"
                                },
                                "uniqueCtr": {
                                  "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                  "type": "number"
                                },
                                "video2SecWatchedActions": {
                                  "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                  "type": "integer"
                                },
                                "video30SecWatchedActions": {
                                  "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                  "type": "integer"
                                },
                                "video6SecFocusedViews": {
                                  "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                  "type": "integer"
                                },
                                "video6SecWatchedActions": {
                                  "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                  "type": "integer"
                                },
                                "videoAvgTimeWatchedActions": {
                                  "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                  "type": "number"
                                },
                                "videoP100WatchedActions": {
                                  "description": "Views reaching 100% of the video's length.",
                                  "type": "integer"
                                },
                                "videoP25WatchedActions": {
                                  "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                  "type": "integer"
                                },
                                "videoP50WatchedActions": {
                                  "description": "Views reaching 50% of the video's length.",
                                  "type": "integer"
                                },
                                "videoP75WatchedActions": {
                                  "description": "Views reaching 75% of the video's length.",
                                  "type": "integer"
                                },
                                "videoP95WatchedActions": {
                                  "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                  "type": "integer"
                                },
                                "videoPlayActions": {
                                  "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                  "type": "integer"
                                },
                                "videoThruplayWatchedActions": {
                                  "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "name": {
                          "type": "string"
                        },
                        "optimizationGoal": {
                          "description": "What the delivery system optimizes for, at ad-set level. The value space depends on `platform`: Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS).",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platform": {
                          "enum": [
                            "facebook",
                            "instagram",
                            "tiktok",
                            "linkedin",
                            "pinterest",
                            "google",
                            "twitter",
                            "openai",
                            "reddit",
                            "microsoft"
                          ],
                          "type": "string"
                        },
                        "platformAdAccountId": {
                          "type": "string"
                        },
                        "platformAdAccountName": {
                          "description": "Human-readable advertiser/account name (Meta `AdAccount.name`, TikTok `advertiser_name`, LinkedIn / X / Pinterest equivalents). Refreshed every sync so platform-side renames propagate within one cycle.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platformAdId": {
                          "type": "string"
                        },
                        "platformAdSetId": {
                          "type": "string"
                        },
                        "platformCampaignId": {
                          "type": "string"
                        },
                        "platformCreatedAt": {
                          "description": "Platform-reported creation timestamp (Meta `created_time`, TikTok `create_time`). Read this field to sort or filter by when the ad was actually created on the platform.",
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platformObjective": {
                          "description": "The platform's own campaign objective, verbatim, alongside the normalized `goal` it maps to. The mapping is many-to-one, so `goal` alone cannot be mapped back to it. Meta: campaign `objective` (e.g.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "promotedObject": {
                          "description": "Meta promoted object containing conversion event details. Structure varies by objective. Only present for Meta ads.",
                          "properties": {
                            "application_id": {
                              "description": "Facebook app ID",
                              "type": "string"
                            },
                            "custom_event_type": {
                              "description": "Conversion event type (e.g. PURCHASE, LEAD, COMPLETE_REGISTRATION, ADD_TO_CART)",
                              "type": "string"
                            },
                            "page_id": {
                              "description": "Facebook page ID",
                              "type": "string"
                            },
                            "pixel_id": {
                              "description": "Meta pixel ID",
                              "type": "string"
                            },
                            "product_set_id": {
                              "description": "Product catalog set ID",
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "rejectionReason": {
                          "type": "string"
                        },
                        "reviewStatus": {
                          "description": "Platform review state of this ad, independent of delivery `status` / `configuredStatus`. Absent when the platform reports no review signal.",
                          "enum": [
                            "in_review",
                            "approved",
                            "rejected",
                            "with_issues"
                          ],
                          "type": "string"
                        },
                        "roasAverageFloor": {
                          "description": "Minimum ROAS as a decimal multiplier (2.0 = 2.0x ROAS). Populated when bidStrategy is `LOWEST_COST_WITH_MIN_ROAS`.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "schedule": {
                          "description": "Delivery window as UTC instants.",
                          "properties": {
                            "endDate": {
                              "format": "date-time",
                              "type": "string"
                            },
                            "startDate": {
                              "format": "date-time",
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "servingStatuses": {
                          "description": "LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn. A campaign can report `status: ACTIVE` and still serve nothing; this array says so.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "status": {
                          "description": "Delivery status. Derived from the platform `effective_status`, so it inherits ancestor pauses (an ACTIVE ad under a PAUSED campaign reads `paused`).",
                          "enum": [
                            "active",
                            "paused",
                            "pending_review",
                            "rejected",
                            "completed",
                            "cancelled",
                            "error"
                          ],
                          "type": "string"
                        },
                        "synced": {
                          "description": "Only on GET /apis/v1/ads/{adId}. An unsynced ad has no `id`.",
                          "type": "boolean"
                        },
                        "targeting": {
                          "description": "The ad set's targeting (age, gender, geo, interests, placements, audience inclusions/exclusions). May be absent if the ad set exposes no targeting or the lookup fails.",
                          "type": "object"
                        },
                        "updatedAt": {
                          "format": "date-time",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "cachedAt": {
                      "description": "Google RSA details cache timestamp.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "darkPost": {
                      "description": "Only when `{adId}` is a Facebook ad dark post with no resolvable ad (then `ad` is null).",
                      "properties": {
                        "adId": {
                          "description": "Always null: Meta exposes no link from a placement dark post to its ad.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "connectionId": {
                          "description": "The ads connection (adc_...) the object belongs to.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "firstSeenAt": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "isDarkPost": {
                          "description": "Always true.",
                          "type": "boolean"
                        },
                        "lastActivityAt": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "pageId": {
                          "type": "string"
                        },
                        "platform": {
                          "enum": [
                            "facebook"
                          ],
                          "type": "string"
                        },
                        "platformAdAccountIds": {
                          "description": "Meta ad accounts (`act_...`) with synced ads on this Page.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "platformPostId": {
                          "description": "The dark post id, `{pageId}_{postId}`.",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "stale": {
                      "description": "Whether Google RSA details use the last successful cached response.",
                      "type": "boolean"
                    },
                    "statusReadAt": {
                      "description": "With `live=true`, when the switches were read from the platform; null when the live read failed and the stored values were returned. Always set on an unsynced Meta ad read with `connectionId`, the time of that read.",
                      "format": "date-time",
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad details"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get ad details",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0afcae3fda7d2922f5bceca8d64691f82ab422024844be0cccea4d325f48fbed"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_adid",
          "method": "GET",
          "path": "/apis/v1/ads/{adId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_adid"
      },
      "put": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Changes an ad's budget, targeting or status. Changes an ad's status, budget, targeting or creative and applies the change on the platform. Patch one or more fields on an ad. Status, budget, targeting, and creative changes are propagated to the platform. ### Per-platform support Meta (Facebook + Instagram): all fields supported.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_adid",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "descriptions": [
                  {
                    "pinnedField": "DESCRIPTION_1",
                    "text": "Connect social accounts and schedule posts with the AIsa API."
                  },
                  {
                    "text": "Build social publishing into your application."
                  }
                ],
                "finalUrls": [
                  "https://example.com/landing"
                ],
                "headlines": [
                  {
                    "pinnedField": "HEADLINE_1",
                    "text": "Social Media API"
                  },
                  {
                    "text": "Schedule Your Posts"
                  },
                  {
                    "text": "Build With AIsa"
                  }
                ]
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "assetGroup": {
                    "additionalProperties": false,
                    "description": "Google Performance Max only. Replaces whole asset roles on the ad's asset group. Returns 422 on any other platform or channel.",
                    "properties": {
                      "businessName": {
                        "description": "Replaces the BUSINESS_NAME asset.",
                        "maxLength": 25,
                        "minLength": 1,
                        "type": "string"
                      },
                      "descriptions": {
                        "description": "Replaces every DESCRIPTION asset. At least one must be 60 characters or fewer.",
                        "items": {
                          "maxLength": 90,
                          "minLength": 1,
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 2,
                        "type": "array",
                        "uniqueItems": true
                      },
                      "finalUrl": {
                        "description": "Replaces the asset group's final URL.",
                        "format": "uri",
                        "pattern": "^https?://",
                        "type": "string"
                      },
                      "headlines": {
                        "description": "Replaces every HEADLINE asset on the group.",
                        "items": {
                          "maxLength": 30,
                          "minLength": 1,
                          "type": "string"
                        },
                        "maxItems": 15,
                        "minItems": 3,
                        "type": "array",
                        "uniqueItems": true
                      },
                      "images": {
                        "additionalProperties": false,
                        "description": "Public HTTP(S) image URLs. Each role you send replaces that role's images; roles you omit stay. GIF, JPEG or PNG, at most 5120 KB per image.",
                        "properties": {
                          "landscape": {
                            "description": "Replaces MARKETING_IMAGE assets. Aspect ratio 1.91:1, minimum 600 x 314 pixels.",
                            "items": {
                              "format": "uri",
                              "pattern": "^https?://",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "logo": {
                            "description": "Replaces LOGO assets. Aspect ratio 1:1, minimum 128 x 128 pixels.",
                            "items": {
                              "format": "uri",
                              "pattern": "^https?://",
                              "type": "string"
                            },
                            "maxItems": 5,
                            "minItems": 1,
                            "type": "array"
                          },
                          "square": {
                            "description": "Replaces SQUARE_MARKETING_IMAGE assets. Aspect ratio 1:1, minimum 300 x 300 pixels.",
                            "items": {
                              "format": "uri",
                              "pattern": "^https?://",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "longHeadline": {
                        "description": "Replaces the LONG_HEADLINE asset.",
                        "maxLength": 90,
                        "minLength": 1,
                        "type": "string"
                      },
                      "youtubeVideoIds": {
                        "description": "Replaces YOUTUBE_VIDEO assets with existing YouTube video ids. Video uploads and arbitrary video URLs are not supported.",
                        "items": {
                          "pattern": "^[A-Za-z0-9_-]{11}$",
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 1,
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "budget": {
                    "properties": {
                      "amount": {
                        "description": "Minimum varies by platform: TikTok=$20, Pinterest=$5, others=$1",
                        "type": "number"
                      },
                      "type": {
                        "description": "OpenAI Ads accepts both and sets the campaign's single spend cap, replacing the previous daily or lifetime cap. A daily cap cannot go back to lifetime (422).",
                        "enum": [
                          "daily",
                          "lifetime"
                        ],
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "creative": {
                    "description": "Replace or patch the ad's creative. Meta, TikTok, and LinkedIn. Meta: patch-style. Pass any subset: omitted fields are preserved from the live creative, including media (`image_hash`/`video_id` reused, no re-upload) and `url_tags`.",
                    "properties": {
                      "body": {
                        "type": "string"
                      },
                      "businessName": {
                        "description": "Google Display only. Replaces the responsive display ad's business name.",
                        "maxLength": 25,
                        "minLength": 1,
                        "type": "string"
                      },
                      "callToAction": {
                        "type": "string"
                      },
                      "catalogFormat": {
                        "description": "Meta catalog template ads only. Rebuilds the creative with this `template_data.format_option` (same mapping as on create) and repoints the ad at the new creative.",
                        "enum": [
                          "single_image",
                          "carousel_images_multi_items",
                          "carousel_images_single_item",
                          "carousel_slideshows"
                        ],
                        "type": "string"
                      },
                      "creativeFeatures": {
                        "additionalProperties": {
                          "enum": [
                            "OPT_IN",
                            "OPT_OUT"
                          ],
                          "type": "string"
                        },
                        "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                        "type": "object"
                      },
                      "description": {
                        "description": "Link description slot (Meta `link_data.description` / `video_data.link_description`, LinkedIn creative description).",
                        "maxLength": 255,
                        "type": "string"
                      },
                      "existingCreativeId": {
                        "description": "Meta only. Repoint the ad at an existing library creative (from GET /apis/v1/ads/creatives); all other creative fields are ignored.",
                        "type": "string"
                      },
                      "headline": {
                        "description": "Meta and LinkedIn (TikTok has no headline slot)",
                        "type": "string"
                      },
                      "imageUrl": {
                        "format": "uri",
                        "type": "string"
                      },
                      "linkUrl": {
                        "format": "uri",
                        "type": "string"
                      },
                      "longHeadline": {
                        "description": "Google Display only. Replaces the responsive display ad's long headline.",
                        "maxLength": 90,
                        "minLength": 1,
                        "type": "string"
                      },
                      "promotion": {
                        "description": "Not supported. Send null or omit the field, and set the Promotion on the ad in Ads Manager. Any object is rejected with 400 invalid_field_value.",
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "squareImageUrl": {
                        "description": "Google Display only. Uploaded as a new square (1:1) marketing image asset that replaces the current one.",
                        "format": "uri",
                        "type": "string"
                      },
                      "videoId": {
                        "description": "Meta only. Reuse an already-uploaded ad video (from POST /apis/v1/ads/videos or GET /apis/v1/ads/videos) instead of re-uploading via videoUrl.",
                        "type": "string"
                      },
                      "videoUrl": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "type": "object"
                  },
                  "demandGen": {
                    "additionalProperties": false,
                    "description": "Google Demand Gen only. Returns 422 on any other platform or channel.",
                    "properties": {
                      "audience": {
                        "additionalProperties": false,
                        "description": "Created as a Google Audience and attached to the ad group. Send at least one dimension. Ids are numeric Google ids (user lists, interest categories, custom audiences) from the same customer.",
                        "properties": {
                          "ageRanges": {
                            "items": {
                              "properties": {
                                "max": {
                                  "description": "Omit for no upper bound.",
                                  "enum": [
                                    24,
                                    34,
                                    44,
                                    54,
                                    64
                                  ],
                                  "type": "integer"
                                },
                                "min": {
                                  "enum": [
                                    18,
                                    25,
                                    35,
                                    45,
                                    55,
                                    65
                                  ],
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "min"
                              ],
                              "type": "object"
                            },
                            "maxItems": 6,
                            "minItems": 1,
                            "type": "array"
                          },
                          "customAudiences": {
                            "items": {
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "genders": {
                            "items": {
                              "enum": [
                                "male",
                                "female",
                                "undetermined"
                              ],
                              "type": "string"
                            },
                            "maxItems": 3,
                            "minItems": 1,
                            "type": "array"
                          },
                          "userInterests": {
                            "items": {
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "userLists": {
                            "items": {
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "audienceId": {
                        "description": "Attach an existing Google Audience by numeric id instead of audience. Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                        "type": "string"
                      },
                      "businessName": {
                        "maxLength": 25,
                        "type": "string"
                      },
                      "callToAction": {
                        "description": "Image and carousel ads only.",
                        "maxLength": 25,
                        "type": "string"
                      },
                      "channels": {
                        "description": "Replaces the ad group's channel controls. Only the listed channels serve; Google Maps, which this list cannot select, is turned off. Omit to leave the ad group's channel controls unchanged.",
                        "items": {
                          "enum": [
                            "youtube_in_stream",
                            "youtube_in_feed",
                            "youtube_shorts",
                            "discover",
                            "gmail",
                            "display"
                          ],
                          "type": "string"
                        },
                        "minItems": 1,
                        "type": "array"
                      },
                      "descriptions": {
                        "items": {
                          "maxLength": 90,
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 1,
                        "type": "array"
                      },
                      "finalUrl": {
                        "format": "uri",
                        "type": "string"
                      },
                      "headlines": {
                        "items": {
                          "maxLength": 40,
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 1,
                        "type": "array"
                      },
                      "images": {
                        "additionalProperties": false,
                        "properties": {
                          "landscape": {
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "logo": {
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "maxItems": 5,
                            "minItems": 1,
                            "type": "array"
                          },
                          "portrait": {
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          },
                          "square": {
                            "items": {
                              "format": "uri",
                              "type": "string"
                            },
                            "maxItems": 20,
                            "minItems": 1,
                            "type": "array"
                          }
                        },
                        "type": "object"
                      },
                      "longHeadlines": {
                        "description": "Video ads only.",
                        "items": {
                          "maxLength": 90,
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 1,
                        "type": "array"
                      },
                      "youtubeVideoIds": {
                        "description": "Video ads only.",
                        "items": {
                          "pattern": "^[A-Za-z0-9_-]{11}$",
                          "type": "string"
                        },
                        "maxItems": 5,
                        "minItems": 1,
                        "type": "array"
                      }
                    },
                    "type": "object"
                  },
                  "descriptions": {
                    "description": "Google Search and Display only. Replaces the complete description list. Search takes 2-4, Display 1-5 and rejects pinnedField. No padding or truncation on update.",
                    "items": {
                      "properties": {
                        "pinnedField": {
                          "description": "Optional fixed description position. Omit to leave the asset unpinned.",
                          "enum": [
                            "DESCRIPTION_1",
                            "DESCRIPTION_2"
                          ],
                          "type": "string"
                        },
                        "text": {
                          "maxLength": 90,
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "text"
                      ],
                      "type": "object"
                    },
                    "maxItems": 5,
                    "minItems": 1,
                    "type": "array"
                  },
                  "finalUrls": {
                    "description": "Google Search and Display only. Replaces final URLs. Omitted lists stay unchanged. For Performance Max use assetGroup.finalUrl.",
                    "items": {
                      "format": "uri",
                      "type": "string"
                    },
                    "minItems": 1,
                    "type": "array"
                  },
                  "headlines": {
                    "description": "Google Search and Display only. Replaces the complete headline list. Search takes 3-15, Display 1-5 and rejects pinnedField; the count is checked once the ad's channel is known. No padding or truncation on update.",
                    "items": {
                      "properties": {
                        "pinnedField": {
                          "description": "Optional fixed headline position. Omit to leave the asset unpinned.",
                          "enum": [
                            "HEADLINE_1",
                            "HEADLINE_2",
                            "HEADLINE_3"
                          ],
                          "type": "string"
                        },
                        "text": {
                          "maxLength": 30,
                          "minLength": 1,
                          "type": "string"
                        }
                      },
                      "required": [
                        "text"
                      ],
                      "type": "object"
                    },
                    "maxItems": 15,
                    "minItems": 1,
                    "type": "array"
                  },
                  "name": {
                    "description": "Rename the ad. Now propagated to Meta (POST /{ad-id}); non-Meta platforms return 501.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "status": {
                    "enum": [
                      "active",
                      "paused"
                    ],
                    "type": "string"
                  },
                  "targeting": {
                    "description": "Targeting update. Meta + TikTok: demographics/interests. Google: keyword and device bid adjustment edits only. LinkedIn: locations, B2B facets, audiences. Pinterest / X: return 501.",
                    "properties": {
                      "advantage_audience": {
                        "description": "Meta only. Omit to preserve the existing setting on update. 0 = disabled, 1 = enabled.",
                        "enum": [
                          0,
                          1
                        ],
                        "type": "integer"
                      },
                      "ageMax": {
                        "maximum": 65,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "ageMin": {
                        "maximum": 65,
                        "minimum": 13,
                        "type": "integer"
                      },
                      "countries": {
                        "description": "ISO 3166-1 alpha-2 codes. On Google this is the FULL new country set for the campaign (same contract as `locations`); on LinkedIn it replaces the campaign's geo criteria.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "devices": {
                        "description": "Google only. The FULL new set of device bid modifiers for the campaign. Entries are a device name alone (targeted, bid modifier reset to 1) or { device, bidModifier }.",
                        "items": {
                          "oneOf": [
                            {
                              "enum": [
                                "MOBILE",
                                "DESKTOP",
                                "TABLET",
                                "CONNECTED_TV"
                              ],
                              "type": "string"
                            },
                            {
                              "properties": {
                                "bidModifier": {
                                  "description": "Google device bid modifier. 0 switches the device off (minus 100%); otherwise 0.1 to 10 (minus 90% to plus 900%). Google rejects any value between 0 and 0.1.",
                                  "maximum": 10,
                                  "minimum": 0,
                                  "type": "number"
                                },
                                "device": {
                                  "enum": [
                                    "MOBILE",
                                    "DESKTOP",
                                    "TABLET",
                                    "CONNECTED_TV"
                                  ],
                                  "type": "string"
                                }
                              },
                              "required": [
                                "device"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "interests": {
                        "description": "Interest objects from /apis/v1/ads/interests. Each must include id and name.",
                        "items": {
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "name"
                          ],
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "keywords": {
                        "description": "Google only. The FULL desired set of positive keywords for the entire ad group. Omit to leave positives unchanged; [] removes all positives. Negatives are independent.",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "matchType": {
                                  "enum": [
                                    "exact",
                                    "phrase",
                                    "broad"
                                  ],
                                  "type": "string"
                                },
                                "text": {
                                  "maxLength": 80,
                                  "type": "string"
                                }
                              },
                              "required": [
                                "text"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      },
                      "languages": {
                        "description": "Google only. The FULL new language set for the campaign, as Google language codes (ISO 639-1, plus variants such as `zh_CN`). An unknown code returns 400.",
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "locations": {
                        "description": "Google and LinkedIn. The FULL new location set for the campaign. Bare country-code array, or an object with countries/regions/cities/zips/metros key lists (`key` from GET /apis/v1/ads/targeting/search?dimension=geo).",
                        "oneOf": [
                          {
                            "items": {
                              "description": "ISO 3166-1 alpha-2 country code.",
                              "type": "string"
                            },
                            "type": "array"
                          },
                          {
                            "properties": {
                              "cities": {
                                "items": {
                                  "properties": {
                                    "key": {
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "countries": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "metros": {
                                "items": {
                                  "properties": {
                                    "key": {
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "regions": {
                                "items": {
                                  "properties": {
                                    "key": {
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "zips": {
                                "items": {
                                  "properties": {
                                    "key": {
                                      "type": "string"
                                    },
                                    "name": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "key"
                                  ],
                                  "type": "object"
                                },
                                "type": "array"
                              }
                            },
                            "type": "object"
                          }
                        ]
                      },
                      "negativeKeywords": {
                        "description": "Google only. The FULL desired set of negative keywords for the entire ad group, independent of positives. Omit to leave negatives unchanged; [] removes all negatives.",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "properties": {
                                "matchType": {
                                  "enum": [
                                    "exact",
                                    "phrase",
                                    "broad"
                                  ],
                                  "type": "string"
                                },
                                "text": {
                                  "maxLength": 80,
                                  "type": "string"
                                }
                              },
                              "required": [
                                "text"
                              ],
                              "type": "object"
                            }
                          ]
                        },
                        "type": "array"
                      }
                    },
                    "type": "object"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ad": {
                      "properties": {
                        "_id": {
                          "type": "string"
                        },
                        "adSetName": {
                          "type": "string"
                        },
                        "adType": {
                          "enum": [
                            "boost",
                            "standalone"
                          ],
                          "type": "string"
                        },
                        "bidAmount": {
                          "description": "Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). Meta: `bid_amount` on the ad set (smallest-denomination int, decoded here).",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "bidStrategy": {
                          "anyOf": [
                            {
                              "description": "Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`.",
                              "enum": [
                                "LOWEST_COST_WITHOUT_CAP",
                                "LOWEST_COST_WITH_BID_CAP",
                                "COST_CAP",
                                "LOWEST_COST_WITH_MIN_ROAS"
                              ],
                              "type": "string"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "Ad-set bid strategy (overrides campaign level on Meta). Populated for Meta and TikTok."
                        },
                        "budget": {
                          "properties": {
                            "amount": {
                              "type": "number"
                            },
                            "daily": {
                              "description": "LinkedIn and X only. The daily budget (LinkedIn: the parent campaign's `dailyBudget`; X: the line item's, or the campaign's when the line item has none).",
                              "type": "number"
                            },
                            "lifetime": {
                              "description": "LinkedIn and X only. The lifetime total (LinkedIn: the parent campaign's `totalBudget`; X: `total_budget_amount_local_micro`, for example the `lifetimeBudgetCap` of a boost), readable even when a daily budget is also set.",
                              "type": "number"
                            },
                            "pacing": {
                              "description": "LinkedIn only. The campaign's `pacingStrategy`: how fast LinkedIn may spend the budget. Typically LINEAR or ACCELERATED; the list is open.",
                              "type": "string"
                            },
                            "type": {
                              "enum": [
                                "daily",
                                "lifetime"
                              ],
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "campaignName": {
                          "type": "string"
                        },
                        "configuredStatus": {
                          "description": "The ad's own on/off switch as configured on the platform, independent of its parents. An ACTIVE ad under a paused ad set or campaign still reads ACTIVE here while `status` reads `paused`. Sources: Meta: `configured_status`.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "costType": {
                          "description": "LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn, refreshed on every sync rather than echoing what was passed on create. `null` for non-LinkedIn ads. `CPM`: cost per thousand impressions.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "createdAt": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "creative": {
                          "description": "Platform-specific creative data. Fields vary by platform.",
                          "properties": {
                            "adFormat": {
                              "description": "LinkedIn only. The LinkedIn ad format, in LinkedIn's own vocabulary: STANDARD_UPDATE, SINGLE_VIDEO, CAROUSEL, NATIVE_DOCUMENT, EVENT, TEXT_AD, SPOTLIGHT, FOLLOW_COMPANY, JOBS, SPONSORED_INMAILS and others.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "assetGroup": {
                              "description": "Google Performance Max creative assets. At least one description must be 60 characters or fewer. Texts within each list must be distinct.",
                              "properties": {
                                "businessName": {
                                  "maxLength": 25,
                                  "minLength": 1,
                                  "type": "string"
                                },
                                "descriptions": {
                                  "description": "At least one description must be 60 characters or fewer.",
                                  "items": {
                                    "maxLength": 90,
                                    "minLength": 1,
                                    "type": "string"
                                  },
                                  "maxItems": 5,
                                  "minItems": 2,
                                  "type": "array",
                                  "uniqueItems": true
                                },
                                "finalUrl": {
                                  "description": "Required destination URL.",
                                  "format": "uri",
                                  "pattern": "^https?://",
                                  "type": "string"
                                },
                                "headlines": {
                                  "items": {
                                    "maxLength": 30,
                                    "minLength": 1,
                                    "type": "string"
                                  },
                                  "maxItems": 15,
                                  "minItems": 3,
                                  "type": "array",
                                  "uniqueItems": true
                                },
                                "images": {
                                  "additionalProperties": true,
                                  "description": "Public HTTP(S) image URLs. GIF, JPEG or PNG, at most 5120 KB per image. Google validates dimensions and aspect ratios.",
                                  "type": "object"
                                },
                                "longHeadline": {
                                  "maxLength": 90,
                                  "minLength": 1,
                                  "type": "string"
                                },
                                "name": {
                                  "description": "Defaults to the request name.",
                                  "maxLength": 128,
                                  "minLength": 1,
                                  "type": "string"
                                },
                                "youtubeVideoId": {
                                  "description": "Optional existing YouTube video id. Google can generate video when omitted. Video uploads and arbitrary video URLs are not supported.",
                                  "pattern": "^[A-Za-z0-9_-]{11}$",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "businessName",
                                "descriptions",
                                "finalUrl",
                                "headlines",
                                "images",
                                "longHeadline"
                              ],
                              "type": "object"
                            },
                            "assetGroupResourceName": {
                              "description": "Google resource name of the created Performance Max asset group.",
                              "type": "string"
                            },
                            "assetResourceName": {
                              "description": "Google Display only. Resource name of the landscape marketing image asset (`creative.imageUrl`), for example customers/1234567890/assets/123.",
                              "type": "string"
                            },
                            "assets": {
                              "description": "Google Display only. Native Google asset resource name of each image on the responsive display ad, keyed by Google's image role.",
                              "properties": {
                                "marketingImages": {
                                  "description": "Landscape (1.91:1) marketing images. The first item matches `assetResourceName`.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "squareMarketingImages": {
                                  "description": "Square (1:1) marketing images.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                }
                              },
                              "type": "object"
                            },
                            "bodies": {
                              "description": "Meta: every primary text variation of the creative (`asset_feed_spec.bodies`), the same shape as the `bodies` create input. Present only with 2 or more texts; a single text is `body`.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "body": {
                              "description": "Ad copy/text",
                              "type": "string"
                            },
                            "callToAction": {
                              "description": "Meta: the call to action type (`call_to_action.type`, or the first `asset_feed_spec.call_to_action_types` entry), e.g. LEARN_MORE or SIGN_UP.",
                              "type": "string"
                            },
                            "carouselCards": {
                              "description": "Meta only today. The carousel's cards in display order, one per Meta `link_data.child_attachments` entry, using the same field names as the `carouselCards` create input. Absent on non-carousel ads and other platforms.",
                              "items": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "type": "array"
                            },
                            "catalog": {
                              "properties": {
                                "format": {
                                  "description": "object_story_spec.template_data.format_option, from catalogFormat.",
                                  "enum": [
                                    "single_image",
                                    "carousel_images_multi_items",
                                    "carousel_images_single_item",
                                    "carousel_slideshows"
                                  ],
                                  "type": "string"
                                },
                                "formatTransformationSpec": {
                                  "description": "The format_transformation_spec sent on the creative, as Meta's raw objects. Present for single_image.",
                                  "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                  },
                                  "type": "array"
                                },
                                "productSetId": {
                                  "description": "The creative's product_set_id.",
                                  "type": "string"
                                }
                              },
                              "type": "object"
                            },
                            "creativeFeatures": {
                              "additionalProperties": {
                                "enum": [
                                  "OPT_IN",
                                  "OPT_OUT"
                                ],
                                "type": "string"
                              },
                              "description": "Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT.",
                              "type": "object"
                            },
                            "creativeId": {
                              "description": "Meta ad creative id backing this ad, refreshed from Meta on every sync. Reusable via existingCreativeId on POST /apis/v1/ads/create, and readable raw through GET /apis/v1/ads/creatives/{creativeId}.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "description": {
                              "description": "Meta: the creative's description under the title (`link_data.description`, `video_data.link_description`, or the first `asset_feed_spec.descriptions` entry).",
                              "type": "string"
                            },
                            "descriptions": {
                              "description": "Google RSA: the description assets as objects (2 to 4). Meta: every description variation of the creative (`asset_feed_spec.descriptions`) as strings, the same shape as the `descriptions` create input.",
                              "items": {
                                "oneOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "additionalProperties": true,
                                    "type": "object"
                                  }
                                ]
                              },
                              "maxItems": 4,
                              "type": "array"
                            },
                            "effectiveInstagramMediaId": {
                              "description": "Meta `effective_instagram_media_id`, the Instagram media ID of the boosted post the ad's engagement lives on. Pass to GET /apis/v1/ads?effectiveInstagramMediaId= to map a Business-Manager-visible IG post back to this ad.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "effectiveObjectStoryId": {
                              "description": "Meta `effective_object_story_id`, the `{pageId}_{postId}` of the Facebook post the ad's engagement (comments) lives on.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "finalUrls": {
                              "description": "Google RSA only. Replaces final URLs. Omitted lists stay unchanged.",
                              "items": {
                                "format": "uri",
                                "type": "string"
                              },
                              "minItems": 1,
                              "type": "array"
                            },
                            "googleDescription": {
                              "description": "Google Ads description",
                              "type": "string"
                            },
                            "googleHeadline": {
                              "description": "Google Ads headline",
                              "type": "string"
                            },
                            "headline": {
                              "description": "Meta: the creative's title (`link_data.name`, `video_data.title`, or the first `asset_feed_spec.titles` entry). Absent when the creative has none.",
                              "type": "string"
                            },
                            "headlines": {
                              "description": "Google RSA: the headline assets as objects (3 to 15). Meta: every title variation of the creative (`asset_feed_spec.titles`) as strings, the same shape as the `headlines` create input.",
                              "items": {
                                "oneOf": [
                                  {
                                    "type": "string"
                                  },
                                  {
                                    "additionalProperties": true,
                                    "type": "object"
                                  }
                                ]
                              },
                              "maxItems": 15,
                              "type": "array"
                            },
                            "imageHash": {
                              "description": "Meta: the ad image hash (`image_hash`), reusable as `imageHash` on POST /apis/v1/ads/create within the same ad account. `thumbnailUrl` and `mediaUrls` carry its stable full resolution permalink when Meta resolves it.",
                              "type": "string"
                            },
                            "imageUrl": {
                              "description": "Alternative image URL",
                              "type": "string"
                            },
                            "instagramPermalinkUrl": {
                              "description": "Meta `instagram_permalink_url`, the public Instagram post URL of the boosted media.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "instagramUserId": {
                              "description": "Meta `instagram_user_id`, the Instagram-scoped business ID that owns the boosted media.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "instagramVideoFallback": {
                              "description": "Meta only. `instagram_video_reuploaded`: the video was copied into the ad account, and the ad still references the original post.",
                              "properties": {
                                "kind": {
                                  "enum": [
                                    "instagram_video_reuploaded",
                                    "instagram_video_rehosted_copy"
                                  ],
                                  "type": "string"
                                },
                                "linkedToOriginalPost": {
                                  "description": "True when the ad still references the original Instagram post and keeps its engagement.",
                                  "type": "boolean"
                                },
                                "platformError": {
                                  "additionalProperties": true,
                                  "description": "Meta's original refusal.",
                                  "type": "object"
                                },
                                "videoId": {
                                  "description": "instagram_video_reuploaded: the copy in the ad account video library (possibly one made by an earlier boost of the same media, reused).",
                                  "type": "string"
                                }
                              },
                              "required": [
                                "kind",
                                "linkedToOriginalPost",
                                "platformError",
                                "videoId"
                              ],
                              "type": "object"
                            },
                            "isServing": {
                              "description": "LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign.",
                              "type": [
                                "boolean",
                                "null"
                              ]
                            },
                            "leadGenFormId": {
                              "description": "Meta: the instant form the call to action opens (`call_to_action.value.lead_gen_form_id`, or the asset feed's `call_to_actions` on a dynamic creative), the same value as the `leadGenFormId` create input. Absent on ads without a lead form.",
                              "type": "string"
                            },
                            "linkUrl": {
                              "description": "Destination URL",
                              "type": "string"
                            },
                            "mediaUrls": {
                              "description": "All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts).",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "objectStoryId": {
                              "description": "Meta creative `object_story_id` (the SHARE reference). Frequently absent, because Meta omits it for SHARE creatives. Use effectiveObjectStoryId instead.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "objectType": {
                              "description": "Meta creative object_type (e.g. SHARE, VIDEO, PRIVACY_CHECK_FAIL, POST_DELETED). Use this to render state-aware previews: when Meta moderation strips image/video fields, only thumbnailUrl at 64x64 is available.",
                              "type": "string"
                            },
                            "pageId": {
                              "description": "Facebook Page backing the creative (Meta only). What the `pageId` filter on /apis/v1/ads, /apis/v1/ads/campaigns and /apis/v1/ads/tree matches against. Absent for non-Meta ads and rare Meta creatives with no page signal.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "pinterestDescription": {
                              "type": "string"
                            },
                            "pinterestImageUrl": {
                              "type": "string"
                            },
                            "pinterestTitle": {
                              "type": "string"
                            },
                            "servingHoldReasons": {
                              "description": "LinkedIn only. Why this specific creative is not being served. Empty when it is serving.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            },
                            "thumbnailUrl": {
                              "description": "Primary thumbnail/image URL",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "urlTags": {
                              "description": "Meta: the creative's `url_tags` query string appended to the destination URL.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "videoId": {
                              "description": "Meta video ID for VIDEO-type ads. Null for non-video ads. Callers that need an embeddable MP4 can call GET /{videoId}?fields=source with the page access token.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "videoUrl": {
                              "description": "Null for non-video ads.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "whatsappPhoneNumber": {
                              "description": "Explicit E.164 WhatsApp number supplied when creating a Meta boost or messaging ad. Absent when omitted by the caller or on older records.",
                              "type": "string"
                            },
                            "youtubeVideoIds": {
                              "description": "Google only. YouTube video ids behind a Video campaign ad (video and responsive video ads) or a Demand Gen video ad, same id as `youtubeVideoId` on Performance Max asset groups.",
                              "items": {
                                "type": "string"
                              },
                              "type": "array"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "creativeType": {
                          "description": "Creative format, classified from the media the creative carries. `null` when the creative carries no media to classify. An unsynced creative and a genuine text-only ad are indistinguishable, so neither is guessed at.",
                          "enum": [
                            "carousel",
                            "video",
                            "document",
                            "image",
                            null
                          ],
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "goal": {
                          "description": "Available goals vary by platform:",
                          "enum": [
                            "engagement",
                            "traffic",
                            "awareness",
                            "video_views",
                            "lead_generation",
                            "lead_conversion",
                            "conversions",
                            "app_promotion",
                            "catalog_sales",
                            "page_likes",
                            "page_visits",
                            "job_applicants"
                          ],
                          "type": "string"
                        },
                        "isExternal": {
                          "description": "True for ads synced from platform ad managers",
                          "type": "boolean"
                        },
                        "metrics": {
                          "anyOf": [
                            {
                              "properties": {
                                "actionValues": {
                                  "additionalProperties": {
                                    "type": "number"
                                  },
                                  "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                  "type": "object"
                                },
                                "actions": {
                                  "additionalProperties": {
                                    "type": "integer"
                                  },
                                  "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                  "type": "object"
                                },
                                "allConversions": {
                                  "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                  "type": "number"
                                },
                                "clicks": {
                                  "type": "integer"
                                },
                                "conversions": {
                                  "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                  "type": "number"
                                },
                                "costPerAction": {
                                  "additionalProperties": {
                                    "type": "number"
                                  },
                                  "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                  "type": "object"
                                },
                                "costPerConversion": {
                                  "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                  "type": "number"
                                },
                                "costPerThruplay": {
                                  "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                  "type": "number"
                                },
                                "cpc": {
                                  "description": "Cost per click",
                                  "type": "number"
                                },
                                "cpm": {
                                  "description": "Cost per 1000 impressions",
                                  "type": "number"
                                },
                                "ctr": {
                                  "description": "Click-through rate (%)",
                                  "type": "number"
                                },
                                "engagement": {
                                  "type": "integer"
                                },
                                "engagementBreakdown": {
                                  "description": "The single `engagement` total, split into the interactions behind it.",
                                  "properties": {
                                    "comments": {
                                      "description": "Comments on the ad's post.",
                                      "type": "integer"
                                    },
                                    "linkClicks": {
                                      "description": "Attributed link clicks (`link_click`). This is the attribution-window count, which differs from the in-session count in the sibling `inlineLinkClicks` field.",
                                      "type": "integer"
                                    },
                                    "pageEngagement": {
                                      "description": "Meta's own page-engagement total (`page_engagement`). Meta-only.",
                                      "type": "integer"
                                    },
                                    "pageLikes": {
                                      "description": "New Page likes attributed to the ad (`like`).",
                                      "type": "integer"
                                    },
                                    "postEngagement": {
                                      "description": "Meta's own post-engagement total (`post_engagement`). Meta-only.",
                                      "type": "integer"
                                    },
                                    "reactions": {
                                      "description": "Reactions on the ad's post (`post_reaction`). For TikTok these are its paid likes.",
                                      "type": "integer"
                                    },
                                    "saves": {
                                      "description": "Saves of the ad's post (`onsite_conversion.post_save`).",
                                      "type": "integer"
                                    },
                                    "shares": {
                                      "description": "Shares of the ad's post. Meta reports these under the action type literally named `post`; TikTok under `share`.",
                                      "type": "integer"
                                    },
                                    "videoViews": {
                                      "description": "Video views, from the `video_view` action. Meta counts a 3-second view; LinkedIn's own `videoViews` threshold (2 continuous seconds, or 25% of the video) lands under the same key, so compare across platforms with care.",
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "funnel": {
                                  "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                  "properties": {
                                    "appInstalls": {
                                      "description": "Mobile app installs attributed to the ad.",
                                      "type": "integer"
                                    },
                                    "cartAdds": {
                                      "description": "Adds to cart (Meta `AddToCart` pixel event).",
                                      "type": "integer"
                                    },
                                    "checkoutsInitiated": {
                                      "description": "Checkouts started (Meta `InitiateCheckout` pixel event).",
                                      "type": "integer"
                                    },
                                    "contentViews": {
                                      "description": "Content views (Meta `ViewContent` pixel event).",
                                      "type": "integer"
                                    },
                                    "landingPageViews": {
                                      "description": "Landing page views: the visitor actually loaded the destination, unlike a link click. Meta `landing_page_view`.",
                                      "type": "integer"
                                    },
                                    "leads": {
                                      "description": "Leads, from either the website pixel or an instant form, whichever the ad uses.",
                                      "type": "integer"
                                    },
                                    "messagingConversationsStarted": {
                                      "description": "Messaging conversations started within 7 days, the headline metric for click-to-WhatsApp and click-to-Messenger ads.",
                                      "type": "integer"
                                    },
                                    "messagingFirstReplies": {
                                      "description": "Messaging threads where the person sent a first reply.",
                                      "type": "integer"
                                    },
                                    "paymentInfoAdds": {
                                      "description": "Payment details added at checkout (Meta `AddPaymentInfo` pixel event).",
                                      "type": "integer"
                                    },
                                    "purchases": {
                                      "description": "Purchases. Pair with `purchaseValue` for revenue.",
                                      "type": "integer"
                                    },
                                    "registrationsCompleted": {
                                      "description": "Completed registrations (Meta `CompleteRegistration` pixel event).",
                                      "type": "integer"
                                    },
                                    "searches": {
                                      "description": "On-site searches (Meta `Search` pixel event).",
                                      "type": "integer"
                                    },
                                    "wishlistAdds": {
                                      "description": "Adds to wishlist (Meta `AddToWishlist` pixel event).",
                                      "type": "integer"
                                    }
                                  },
                                  "type": "object"
                                },
                                "impressions": {
                                  "type": "integer"
                                },
                                "inlineLinkClickCtr": {
                                  "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                  "type": "number"
                                },
                                "inlineLinkClicks": {
                                  "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                  "type": "integer"
                                },
                                "lastSyncedAt": {
                                  "description": "Present on individual ads only, not on campaign aggregations",
                                  "format": "date-time",
                                  "type": "string"
                                },
                                "outboundClicks": {
                                  "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                  "type": "integer"
                                },
                                "outboundClicksCtr": {
                                  "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                  "type": "number"
                                },
                                "purchaseValue": {
                                  "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                  "type": "number"
                                },
                                "reach": {
                                  "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                  "type": "integer"
                                },
                                "roas": {
                                  "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                  "type": "number"
                                },
                                "spend": {
                                  "type": "number"
                                },
                                "uniqueClicks": {
                                  "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                  "type": "integer"
                                },
                                "uniqueCtr": {
                                  "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                  "type": "number"
                                },
                                "video2SecWatchedActions": {
                                  "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                  "type": "integer"
                                },
                                "video30SecWatchedActions": {
                                  "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                  "type": "integer"
                                },
                                "video6SecFocusedViews": {
                                  "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                  "type": "integer"
                                },
                                "video6SecWatchedActions": {
                                  "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                  "type": "integer"
                                },
                                "videoAvgTimeWatchedActions": {
                                  "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                  "type": "number"
                                },
                                "videoP100WatchedActions": {
                                  "description": "Views reaching 100% of the video's length.",
                                  "type": "integer"
                                },
                                "videoP25WatchedActions": {
                                  "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                  "type": "integer"
                                },
                                "videoP50WatchedActions": {
                                  "description": "Views reaching 50% of the video's length.",
                                  "type": "integer"
                                },
                                "videoP75WatchedActions": {
                                  "description": "Views reaching 75% of the video's length.",
                                  "type": "integer"
                                },
                                "videoP95WatchedActions": {
                                  "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                  "type": "integer"
                                },
                                "videoPlayActions": {
                                  "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                  "type": "integer"
                                },
                                "videoThruplayWatchedActions": {
                                  "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "name": {
                          "type": "string"
                        },
                        "optimizationGoal": {
                          "description": "What the delivery system optimizes for, at ad-set level. The value space depends on `platform`: Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS).",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platform": {
                          "enum": [
                            "facebook",
                            "instagram",
                            "tiktok",
                            "linkedin",
                            "pinterest",
                            "google",
                            "twitter",
                            "openai",
                            "reddit",
                            "microsoft"
                          ],
                          "type": "string"
                        },
                        "platformAdAccountId": {
                          "type": "string"
                        },
                        "platformAdAccountName": {
                          "description": "Human-readable advertiser/account name (Meta `AdAccount.name`, TikTok `advertiser_name`, LinkedIn / X / Pinterest equivalents). Refreshed every sync so platform-side renames propagate within one cycle.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platformAdId": {
                          "type": "string"
                        },
                        "platformAdSetId": {
                          "type": "string"
                        },
                        "platformCampaignId": {
                          "type": "string"
                        },
                        "platformCreatedAt": {
                          "description": "Platform-reported creation timestamp (Meta `created_time`, TikTok `create_time`). Read this field to sort or filter by when the ad was actually created on the platform.",
                          "format": "date-time",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "platformObjective": {
                          "description": "The platform's own campaign objective, verbatim, alongside the normalized `goal` it maps to. The mapping is many-to-one, so `goal` alone cannot be mapped back to it. Meta: campaign `objective` (e.g.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "promotedObject": {
                          "description": "Meta promoted object containing conversion event details. Structure varies by objective. Only present for Meta ads.",
                          "properties": {
                            "application_id": {
                              "description": "Facebook app ID",
                              "type": "string"
                            },
                            "custom_event_type": {
                              "description": "Conversion event type (e.g. PURCHASE, LEAD, COMPLETE_REGISTRATION, ADD_TO_CART)",
                              "type": "string"
                            },
                            "page_id": {
                              "description": "Facebook page ID",
                              "type": "string"
                            },
                            "pixel_id": {
                              "description": "Meta pixel ID",
                              "type": "string"
                            },
                            "product_set_id": {
                              "description": "Product catalog set ID",
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "rejectionReason": {
                          "type": "string"
                        },
                        "reviewStatus": {
                          "description": "Platform review state of this ad, independent of delivery `status` / `configuredStatus`. Absent when the platform reports no review signal.",
                          "enum": [
                            "in_review",
                            "approved",
                            "rejected",
                            "with_issues"
                          ],
                          "type": "string"
                        },
                        "roasAverageFloor": {
                          "description": "Minimum ROAS as a decimal multiplier (2.0 = 2.0x ROAS). Populated when bidStrategy is `LOWEST_COST_WITH_MIN_ROAS`.",
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "schedule": {
                          "description": "Delivery window as UTC instants.",
                          "properties": {
                            "endDate": {
                              "format": "date-time",
                              "type": "string"
                            },
                            "startDate": {
                              "format": "date-time",
                              "type": "string"
                            }
                          },
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "servingStatuses": {
                          "description": "LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn. A campaign can report `status: ACTIVE` and still serve nothing; this array says so.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "status": {
                          "description": "Delivery status. Derived from the platform `effective_status`, so it inherits ancestor pauses (an ACTIVE ad under a PAUSED campaign reads `paused`).",
                          "enum": [
                            "active",
                            "paused",
                            "pending_review",
                            "rejected",
                            "completed",
                            "cancelled",
                            "error"
                          ],
                          "type": "string"
                        },
                        "synced": {
                          "description": "Only on GET /apis/v1/ads/{adId}. An unsynced ad has no `id`.",
                          "type": "boolean"
                        },
                        "targeting": {
                          "description": "The ad set's targeting (age, gender, geo, interests, placements, audience inclusions/exclusions). May be absent if the ad set exposes no targeting or the lookup fails.",
                          "type": "object"
                        },
                        "updatedAt": {
                          "format": "date-time",
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad updated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Update ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "86d8b30db356b61b2170fa472fc50e6acae73c368fe3c7da6366b0ab7e1d598a"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_adid",
          "method": "PUT",
          "path": "/apis/v1/ads/{adId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_adid"
      }
    },
    "/apis/v1/ads/{adId}/analytics": {
      "get": {
        "description": "Ad Insights. Read only. Returns one ad's performance summary and daily timeline, with optional audience breakdowns on Meta, TikTok and LinkedIn. It includes summary metrics, a daily timeline over the requested date range, and optional demographic breakdowns (Meta, TikTok and LinkedIn only). If no date range is provided, defaults to the last 90 days. Date range is capped at 730 days max. ### History\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_adid_analytics",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Start of date range (YYYY-MM-DD). Defaults to 90 days ago.",
            "in": "query",
            "name": "fromDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End of date range (YYYY-MM-DD). Defaults to today. Max 730-day range.",
            "in": "query",
            "name": "toDate",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Comma-separated breakdown dimensions. Meta: age, gender, country, publisher_platform, device_platform, region, platform_position, impression_device, video_asset, image_asset, body_asset, title_asset.",
            "in": "query",
            "name": "breakdowns",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ad": {
                      "properties": {
                        "currency": {
                          "description": "ISO 4217 code of the ad account that owns this ad (e.g. USD, THB, INR). All money values in `summary` and `daily` are in this currency. Null only on legacy ads synced before currency was persisted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "platform": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "analytics": {
                      "properties": {
                        "breakdownDroppedMetrics": {
                          "additionalProperties": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "description": "TikTok only: metric names TikTok refused for a breakdown, keyed by the requested breakdown (e.g. total_purchase and total_purchase_value have no relation to platform, ac or language). Absent when no metric was refused.",
                          "type": "object"
                        },
                        "breakdownErrors": {
                          "description": "TikTok only: breakdowns the platform failed to return (rate limit, permission, rejected query). Each one is an empty array under breakdowns; summary and daily are unaffected. Absent when every breakdown answered.",
                          "items": {
                            "properties": {
                              "breakdown": {
                                "type": "string"
                              },
                              "message": {
                                "description": "The platform's error message.",
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "breakdownHints": {
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "Guidance for some names in unsupportedBreakdowns, keyed by that name (e.g. placement on Meta points at publisher_platform and platform_position; platform_position on TikTok points at placement). Absent when no unsupported name has a hint.",
                          "type": "object"
                        },
                        "breakdowns": {
                          "additionalProperties": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "description": "Requested demographic breakdowns, keyed by dimension. Fetched live from the platform per request and never stored, so these rows can carry fields the stored `summary` and `daily` series do not.",
                          "type": "object"
                        },
                        "breakdownsRange": {
                          "description": "TikTok only, present when the requested range is longer than the 365 days TikTok serves per breakdown: the window the breakdowns cover (the last 365 days of the range). summary and daily still cover the full range.",
                          "properties": {
                            "fromDate": {
                              "format": "date",
                              "type": "string"
                            },
                            "toDate": {
                              "format": "date",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "daily": {
                          "items": {
                            "properties": {
                              "actionValues": {
                                "additionalProperties": true,
                                "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                "type": "object"
                              },
                              "actions": {
                                "additionalProperties": true,
                                "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                "type": "object"
                              },
                              "allConversions": {
                                "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                "type": "number"
                              },
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                "type": "number"
                              },
                              "costPerAction": {
                                "additionalProperties": true,
                                "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                "type": "object"
                              },
                              "costPerConversion": {
                                "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                "type": "number"
                              },
                              "costPerThruplay": {
                                "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                "type": "number"
                              },
                              "cpc": {
                                "description": "Cost per click",
                                "type": "number"
                              },
                              "cpm": {
                                "description": "Cost per 1000 impressions",
                                "type": "number"
                              },
                              "ctr": {
                                "description": "Click-through rate (%)",
                                "type": "number"
                              },
                              "date": {
                                "format": "date",
                                "type": "string"
                              },
                              "engagement": {
                                "type": "integer"
                              },
                              "engagementBreakdown": {
                                "additionalProperties": true,
                                "description": "The single `engagement` total, split into the interactions behind it.",
                                "type": "object"
                              },
                              "funnel": {
                                "additionalProperties": true,
                                "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                "type": "object"
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "inlineLinkClickCtr": {
                                "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "inlineLinkClicks": {
                                "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                "type": "integer"
                              },
                              "lastSyncedAt": {
                                "description": "Present on individual ads only, not on campaign aggregations",
                                "format": "date-time",
                                "type": "string"
                              },
                              "outboundClicks": {
                                "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                "type": "integer"
                              },
                              "outboundClicksCtr": {
                                "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "purchaseValue": {
                                "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                "type": "number"
                              },
                              "reach": {
                                "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                "type": "integer"
                              },
                              "roas": {
                                "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                "type": "number"
                              },
                              "spend": {
                                "type": "number"
                              },
                              "uniqueClicks": {
                                "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                "type": "integer"
                              },
                              "uniqueCtr": {
                                "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                "type": "number"
                              },
                              "video2SecWatchedActions": {
                                "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                "type": "integer"
                              },
                              "video30SecWatchedActions": {
                                "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                "type": "integer"
                              },
                              "video6SecFocusedViews": {
                                "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                "type": "integer"
                              },
                              "video6SecWatchedActions": {
                                "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                "type": "integer"
                              },
                              "videoAvgTimeWatchedActions": {
                                "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                "type": "number"
                              },
                              "videoP100WatchedActions": {
                                "description": "Views reaching 100% of the video's length.",
                                "type": "integer"
                              },
                              "videoP25WatchedActions": {
                                "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                "type": "integer"
                              },
                              "videoP50WatchedActions": {
                                "description": "Views reaching 50% of the video's length.",
                                "type": "integer"
                              },
                              "videoP75WatchedActions": {
                                "description": "Views reaching 75% of the video's length.",
                                "type": "integer"
                              },
                              "videoP95WatchedActions": {
                                "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                "type": "integer"
                              },
                              "videoPlayActions": {
                                "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                "type": "integer"
                              },
                              "videoThruplayWatchedActions": {
                                "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "summary": {
                          "properties": {
                            "actionValues": {
                              "additionalProperties": {
                                "type": "number"
                              },
                              "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                              "type": "object"
                            },
                            "actions": {
                              "additionalProperties": {
                                "type": "integer"
                              },
                              "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                              "type": "object"
                            },
                            "allConversions": {
                              "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                              "type": "number"
                            },
                            "clicks": {
                              "type": "integer"
                            },
                            "conversions": {
                              "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                              "type": "number"
                            },
                            "costPerAction": {
                              "additionalProperties": {
                                "type": "number"
                              },
                              "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                              "type": "object"
                            },
                            "costPerConversion": {
                              "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                              "type": "number"
                            },
                            "costPerThruplay": {
                              "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                              "type": "number"
                            },
                            "cpc": {
                              "description": "Cost per click",
                              "type": "number"
                            },
                            "cpm": {
                              "description": "Cost per 1000 impressions",
                              "type": "number"
                            },
                            "ctr": {
                              "description": "Click-through rate (%)",
                              "type": "number"
                            },
                            "engagement": {
                              "type": "integer"
                            },
                            "engagementBreakdown": {
                              "description": "The single `engagement` total, split into the interactions behind it.",
                              "properties": {
                                "comments": {
                                  "description": "Comments on the ad's post.",
                                  "type": "integer"
                                },
                                "linkClicks": {
                                  "description": "Attributed link clicks (`link_click`). This is the attribution-window count, which differs from the in-session count in the sibling `inlineLinkClicks` field.",
                                  "type": "integer"
                                },
                                "pageEngagement": {
                                  "description": "Meta's own page-engagement total (`page_engagement`). Meta-only.",
                                  "type": "integer"
                                },
                                "pageLikes": {
                                  "description": "New Page likes attributed to the ad (`like`).",
                                  "type": "integer"
                                },
                                "postEngagement": {
                                  "description": "Meta's own post-engagement total (`post_engagement`). Meta-only.",
                                  "type": "integer"
                                },
                                "reactions": {
                                  "description": "Reactions on the ad's post (`post_reaction`). For TikTok these are its paid likes.",
                                  "type": "integer"
                                },
                                "saves": {
                                  "description": "Saves of the ad's post (`onsite_conversion.post_save`).",
                                  "type": "integer"
                                },
                                "shares": {
                                  "description": "Shares of the ad's post. Meta reports these under the action type literally named `post`; TikTok under `share`.",
                                  "type": "integer"
                                },
                                "videoViews": {
                                  "description": "Video views, from the `video_view` action. Meta counts a 3-second view; LinkedIn's own `videoViews` threshold (2 continuous seconds, or 25% of the video) lands under the same key, so compare across platforms with care.",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "funnel": {
                              "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                              "properties": {
                                "appInstalls": {
                                  "description": "Mobile app installs attributed to the ad.",
                                  "type": "integer"
                                },
                                "cartAdds": {
                                  "description": "Adds to cart (Meta `AddToCart` pixel event).",
                                  "type": "integer"
                                },
                                "checkoutsInitiated": {
                                  "description": "Checkouts started (Meta `InitiateCheckout` pixel event).",
                                  "type": "integer"
                                },
                                "contentViews": {
                                  "description": "Content views (Meta `ViewContent` pixel event).",
                                  "type": "integer"
                                },
                                "landingPageViews": {
                                  "description": "Landing page views: the visitor actually loaded the destination, unlike a link click. Meta `landing_page_view`.",
                                  "type": "integer"
                                },
                                "leads": {
                                  "description": "Leads, from either the website pixel or an instant form, whichever the ad uses.",
                                  "type": "integer"
                                },
                                "messagingConversationsStarted": {
                                  "description": "Messaging conversations started within 7 days, the headline metric for click-to-WhatsApp and click-to-Messenger ads.",
                                  "type": "integer"
                                },
                                "messagingFirstReplies": {
                                  "description": "Messaging threads where the person sent a first reply.",
                                  "type": "integer"
                                },
                                "paymentInfoAdds": {
                                  "description": "Payment details added at checkout (Meta `AddPaymentInfo` pixel event).",
                                  "type": "integer"
                                },
                                "purchases": {
                                  "description": "Purchases. Pair with `purchaseValue` for revenue.",
                                  "type": "integer"
                                },
                                "registrationsCompleted": {
                                  "description": "Completed registrations (Meta `CompleteRegistration` pixel event).",
                                  "type": "integer"
                                },
                                "searches": {
                                  "description": "On-site searches (Meta `Search` pixel event).",
                                  "type": "integer"
                                },
                                "wishlistAdds": {
                                  "description": "Adds to wishlist (Meta `AddToWishlist` pixel event).",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "impressions": {
                              "type": "integer"
                            },
                            "inlineLinkClickCtr": {
                              "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                              "type": "number"
                            },
                            "inlineLinkClicks": {
                              "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                              "type": "integer"
                            },
                            "lastSyncedAt": {
                              "description": "Present on individual ads only, not on campaign aggregations",
                              "format": "date-time",
                              "type": "string"
                            },
                            "outboundClicks": {
                              "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                              "type": "integer"
                            },
                            "outboundClicksCtr": {
                              "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                              "type": "number"
                            },
                            "purchaseValue": {
                              "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                              "type": "number"
                            },
                            "reach": {
                              "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                              "type": "integer"
                            },
                            "roas": {
                              "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                              "type": "number"
                            },
                            "spend": {
                              "type": "number"
                            },
                            "uniqueClicks": {
                              "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                              "type": "integer"
                            },
                            "uniqueCtr": {
                              "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                              "type": "number"
                            },
                            "video2SecWatchedActions": {
                              "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                              "type": "integer"
                            },
                            "video30SecWatchedActions": {
                              "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                              "type": "integer"
                            },
                            "video6SecFocusedViews": {
                              "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                              "type": "integer"
                            },
                            "video6SecWatchedActions": {
                              "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                              "type": "integer"
                            },
                            "videoAvgTimeWatchedActions": {
                              "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                              "type": "number"
                            },
                            "videoP100WatchedActions": {
                              "description": "Views reaching 100% of the video's length.",
                              "type": "integer"
                            },
                            "videoP25WatchedActions": {
                              "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                              "type": "integer"
                            },
                            "videoP50WatchedActions": {
                              "description": "Views reaching 50% of the video's length.",
                              "type": "integer"
                            },
                            "videoP75WatchedActions": {
                              "description": "Views reaching 75% of the video's length.",
                              "type": "integer"
                            },
                            "videoP95WatchedActions": {
                              "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                              "type": "integer"
                            },
                            "videoPlayActions": {
                              "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                              "type": "integer"
                            },
                            "videoThruplayWatchedActions": {
                              "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                              "type": "integer"
                            }
                          },
                          "type": "object"
                        },
                        "unsupportedBreakdowns": {
                          "description": "Requested breakdowns this platform cannot break down by (e.g. region on TikTok, any breakdown on Google). Absent when every requested breakdown is supported.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    },
                    "backfillPending": {
                      "description": "Meta only. Present and true while historical data is being backfilled.",
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad analytics"
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ad": {
                      "properties": {
                        "currency": {
                          "description": "ISO 4217 code of the ad account that owns this ad (e.g. USD, THB, INR). All money values in `summary` and `daily` are in this currency. Null only on legacy ads synced before currency was persisted.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "platform": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        }
                      },
                      "type": "object"
                    },
                    "analytics": {
                      "properties": {
                        "breakdownDroppedMetrics": {
                          "additionalProperties": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "description": "TikTok only: metric names TikTok refused for a breakdown, keyed by the requested breakdown (e.g. total_purchase and total_purchase_value have no relation to platform, ac or language). Absent when no metric was refused.",
                          "type": "object"
                        },
                        "breakdownErrors": {
                          "description": "TikTok only: breakdowns the platform failed to return (rate limit, permission, rejected query). Each one is an empty array under breakdowns; summary and daily are unaffected. Absent when every breakdown answered.",
                          "items": {
                            "properties": {
                              "breakdown": {
                                "type": "string"
                              },
                              "message": {
                                "description": "The platform's error message.",
                                "type": "string"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "breakdownHints": {
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "Guidance for some names in unsupportedBreakdowns, keyed by that name (e.g. placement on Meta points at publisher_platform and platform_position; platform_position on TikTok points at placement). Absent when no unsupported name has a hint.",
                          "type": "object"
                        },
                        "breakdowns": {
                          "additionalProperties": {
                            "items": {
                              "additionalProperties": true,
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "description": "Requested demographic breakdowns, keyed by dimension. Fetched live from the platform per request and never stored, so these rows can carry fields the stored `summary` and `daily` series do not.",
                          "type": "object"
                        },
                        "breakdownsRange": {
                          "description": "TikTok only, present when the requested range is longer than the 365 days TikTok serves per breakdown: the window the breakdowns cover (the last 365 days of the range). summary and daily still cover the full range.",
                          "properties": {
                            "fromDate": {
                              "format": "date",
                              "type": "string"
                            },
                            "toDate": {
                              "format": "date",
                              "type": "string"
                            }
                          },
                          "type": "object"
                        },
                        "daily": {
                          "items": {
                            "properties": {
                              "actionValues": {
                                "additionalProperties": true,
                                "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                                "type": "object"
                              },
                              "actions": {
                                "additionalProperties": true,
                                "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                                "type": "object"
                              },
                              "allConversions": {
                                "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                                "type": "number"
                              },
                              "clicks": {
                                "type": "integer"
                              },
                              "conversions": {
                                "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                                "type": "number"
                              },
                              "costPerAction": {
                                "additionalProperties": true,
                                "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                                "type": "object"
                              },
                              "costPerConversion": {
                                "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                                "type": "number"
                              },
                              "costPerThruplay": {
                                "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                                "type": "number"
                              },
                              "cpc": {
                                "description": "Cost per click",
                                "type": "number"
                              },
                              "cpm": {
                                "description": "Cost per 1000 impressions",
                                "type": "number"
                              },
                              "ctr": {
                                "description": "Click-through rate (%)",
                                "type": "number"
                              },
                              "date": {
                                "format": "date",
                                "type": "string"
                              },
                              "engagement": {
                                "type": "integer"
                              },
                              "engagementBreakdown": {
                                "additionalProperties": true,
                                "description": "The single `engagement` total, split into the interactions behind it.",
                                "type": "object"
                              },
                              "funnel": {
                                "additionalProperties": true,
                                "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                                "type": "object"
                              },
                              "impressions": {
                                "type": "integer"
                              },
                              "inlineLinkClickCtr": {
                                "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "inlineLinkClicks": {
                                "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                                "type": "integer"
                              },
                              "lastSyncedAt": {
                                "description": "Present on individual ads only, not on campaign aggregations",
                                "format": "date-time",
                                "type": "string"
                              },
                              "outboundClicks": {
                                "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                                "type": "integer"
                              },
                              "outboundClicksCtr": {
                                "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                                "type": "number"
                              },
                              "purchaseValue": {
                                "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                                "type": "number"
                              },
                              "reach": {
                                "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                                "type": "integer"
                              },
                              "roas": {
                                "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                                "type": "number"
                              },
                              "spend": {
                                "type": "number"
                              },
                              "uniqueClicks": {
                                "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                                "type": "integer"
                              },
                              "uniqueCtr": {
                                "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                                "type": "number"
                              },
                              "video2SecWatchedActions": {
                                "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                                "type": "integer"
                              },
                              "video30SecWatchedActions": {
                                "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                                "type": "integer"
                              },
                              "video6SecFocusedViews": {
                                "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                                "type": "integer"
                              },
                              "video6SecWatchedActions": {
                                "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                                "type": "integer"
                              },
                              "videoAvgTimeWatchedActions": {
                                "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                                "type": "number"
                              },
                              "videoP100WatchedActions": {
                                "description": "Views reaching 100% of the video's length.",
                                "type": "integer"
                              },
                              "videoP25WatchedActions": {
                                "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                                "type": "integer"
                              },
                              "videoP50WatchedActions": {
                                "description": "Views reaching 50% of the video's length.",
                                "type": "integer"
                              },
                              "videoP75WatchedActions": {
                                "description": "Views reaching 75% of the video's length.",
                                "type": "integer"
                              },
                              "videoP95WatchedActions": {
                                "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                                "type": "integer"
                              },
                              "videoPlayActions": {
                                "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                                "type": "integer"
                              },
                              "videoThruplayWatchedActions": {
                                "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                                "type": "integer"
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "summary": {
                          "properties": {
                            "actionValues": {
                              "additionalProperties": {
                                "type": "number"
                              },
                              "description": "Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Meta and TikTok; other platforms return {}. Same history note as `actions`.",
                              "type": "object"
                            },
                            "actions": {
                              "additionalProperties": {
                                "type": "integer"
                              },
                              "description": "Per-action-type counts summed over the date range, keyed by the platform's action-type names. Keys differ by platform, so branch on the ad's platform when interpreting them. Empty object when no actions are reported.",
                              "type": "object"
                            },
                            "allConversions": {
                              "description": "All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.",
                              "type": "number"
                            },
                            "clicks": {
                              "type": "integer"
                            },
                            "conversions": {
                              "description": "Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google also reports modeled conversions, so values like 0.347 are normal.",
                              "type": "number"
                            },
                            "costPerAction": {
                              "additionalProperties": {
                                "type": "number"
                              },
                              "description": "Derived `spend / actions[type]` for every action type with a non-zero count, in ad-account native currency. Same keys as `actions`. Rounded to 4 decimals, because cheap actions cost well under a cent.",
                              "type": "object"
                            },
                            "costPerConversion": {
                              "description": "Derived spend / conversions in the same currency as spend. 0 when conversions is 0.",
                              "type": "number"
                            },
                            "costPerThruplay": {
                              "description": "Derived `spend / videoThruplayWatchedActions`, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only).",
                              "type": "number"
                            },
                            "cpc": {
                              "description": "Cost per click",
                              "type": "number"
                            },
                            "cpm": {
                              "description": "Cost per 1000 impressions",
                              "type": "number"
                            },
                            "ctr": {
                              "description": "Click-through rate (%)",
                              "type": "number"
                            },
                            "engagement": {
                              "type": "integer"
                            },
                            "engagementBreakdown": {
                              "description": "The single `engagement` total, split into the interactions behind it.",
                              "properties": {
                                "comments": {
                                  "description": "Comments on the ad's post.",
                                  "type": "integer"
                                },
                                "linkClicks": {
                                  "description": "Attributed link clicks (`link_click`). This is the attribution-window count, which differs from the in-session count in the sibling `inlineLinkClicks` field.",
                                  "type": "integer"
                                },
                                "pageEngagement": {
                                  "description": "Meta's own page-engagement total (`page_engagement`). Meta-only.",
                                  "type": "integer"
                                },
                                "pageLikes": {
                                  "description": "New Page likes attributed to the ad (`like`).",
                                  "type": "integer"
                                },
                                "postEngagement": {
                                  "description": "Meta's own post-engagement total (`post_engagement`). Meta-only.",
                                  "type": "integer"
                                },
                                "reactions": {
                                  "description": "Reactions on the ad's post (`post_reaction`). For TikTok these are its paid likes.",
                                  "type": "integer"
                                },
                                "saves": {
                                  "description": "Saves of the ad's post (`onsite_conversion.post_save`).",
                                  "type": "integer"
                                },
                                "shares": {
                                  "description": "Shares of the ad's post. Meta reports these under the action type literally named `post`; TikTok under `share`.",
                                  "type": "integer"
                                },
                                "videoViews": {
                                  "description": "Video views, from the `video_view` action. Meta counts a 3-second view; LinkedIn's own `videoViews` threshold (2 continuous seconds, or 25% of the video) lands under the same key, so compare across platforms with care.",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "funnel": {
                              "description": "Named conversion-funnel steps, resolved from the same data as `actions` so you never have to parse action-type strings yourself.",
                              "properties": {
                                "appInstalls": {
                                  "description": "Mobile app installs attributed to the ad.",
                                  "type": "integer"
                                },
                                "cartAdds": {
                                  "description": "Adds to cart (Meta `AddToCart` pixel event).",
                                  "type": "integer"
                                },
                                "checkoutsInitiated": {
                                  "description": "Checkouts started (Meta `InitiateCheckout` pixel event).",
                                  "type": "integer"
                                },
                                "contentViews": {
                                  "description": "Content views (Meta `ViewContent` pixel event).",
                                  "type": "integer"
                                },
                                "landingPageViews": {
                                  "description": "Landing page views: the visitor actually loaded the destination, unlike a link click. Meta `landing_page_view`.",
                                  "type": "integer"
                                },
                                "leads": {
                                  "description": "Leads, from either the website pixel or an instant form, whichever the ad uses.",
                                  "type": "integer"
                                },
                                "messagingConversationsStarted": {
                                  "description": "Messaging conversations started within 7 days, the headline metric for click-to-WhatsApp and click-to-Messenger ads.",
                                  "type": "integer"
                                },
                                "messagingFirstReplies": {
                                  "description": "Messaging threads where the person sent a first reply.",
                                  "type": "integer"
                                },
                                "paymentInfoAdds": {
                                  "description": "Payment details added at checkout (Meta `AddPaymentInfo` pixel event).",
                                  "type": "integer"
                                },
                                "purchases": {
                                  "description": "Purchases. Pair with `purchaseValue` for revenue.",
                                  "type": "integer"
                                },
                                "registrationsCompleted": {
                                  "description": "Completed registrations (Meta `CompleteRegistration` pixel event).",
                                  "type": "integer"
                                },
                                "searches": {
                                  "description": "On-site searches (Meta `Search` pixel event).",
                                  "type": "integer"
                                },
                                "wishlistAdds": {
                                  "description": "Adds to wishlist (Meta `AddToWishlist` pixel event).",
                                  "type": "integer"
                                }
                              },
                              "type": "object"
                            },
                            "impressions": {
                              "type": "integer"
                            },
                            "inlineLinkClickCtr": {
                              "description": "Derived `inlineLinkClicks / impressions * 100`, recomputed from sums at every rollup level.",
                              "type": "number"
                            },
                            "inlineLinkClicks": {
                              "description": "In-session link clicks. Differs from the attributed `link_click` count in `actions`/`engagementBreakdown.linkClicks`, which uses the attribution window. Meta-only.",
                              "type": "integer"
                            },
                            "lastSyncedAt": {
                              "description": "Present on individual ads only, not on campaign aggregations",
                              "format": "date-time",
                              "type": "string"
                            },
                            "outboundClicks": {
                              "description": "Clicks leading off Meta's surfaces to the advertiser's destination. Meta-only; other platforms report 0.",
                              "type": "integer"
                            },
                            "outboundClicksCtr": {
                              "description": "Derived `outboundClicks / impressions * 100`, recomputed from sums at every rollup level.",
                              "type": "number"
                            },
                            "purchaseValue": {
                              "description": "Convenience sum of purchase-type action values, in ad-account native currency. 0 when the campaign has no purchase event configured.",
                              "type": "number"
                            },
                            "reach": {
                              "description": "Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform's own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery).",
                              "type": "integer"
                            },
                            "roas": {
                              "description": "Return on ad spend, derived as `purchaseValue / spend`. 0 when `spend` is 0. Equivalent to Meta's `purchase_roas` under default attribution.",
                              "type": "number"
                            },
                            "spend": {
                              "type": "number"
                            },
                            "uniqueClicks": {
                              "description": "People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as `reach`). Meta-only.",
                              "type": "integer"
                            },
                            "uniqueCtr": {
                              "description": "Derived `uniqueClicks / impressions * 100` (NOT Meta's reach-based unique_ctr). Inherits the non-additivity caveat of `uniqueClicks`.",
                              "type": "number"
                            },
                            "video2SecWatchedActions": {
                              "description": "Plays of at least 2 seconds, replays excluded. Hook rate = video2SecWatchedActions / impressions. Sources: TikTok `video_watched_2s` (TikTok only; Meta's closest field, 2-second continuous plays, is not synced).",
                              "type": "integer"
                            },
                            "video30SecWatchedActions": {
                              "description": "Views of at least 30 seconds (or to the end, for shorter videos).",
                              "type": "integer"
                            },
                            "video6SecFocusedViews": {
                              "description": "TikTok's 6-second focused views: plays of at least 6 seconds (or to the end, for shorter videos) or with an interaction in the first 6 seconds, so it is at least `video6SecWatchedActions`. Sources: TikTok `engaged_view` (TikTok only).",
                              "type": "integer"
                            },
                            "video6SecWatchedActions": {
                              "description": "Plays of at least 6 seconds, replays excluded. Hold rate = video6SecWatchedActions / video2SecWatchedActions. Sources: TikTok `video_watched_6s` (TikTok only). Same history note as `video2SecWatchedActions`.",
                              "type": "integer"
                            },
                            "videoAvgTimeWatchedActions": {
                              "description": "Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages.",
                              "type": "number"
                            },
                            "videoP100WatchedActions": {
                              "description": "Views reaching 100% of the video's length.",
                              "type": "integer"
                            },
                            "videoP25WatchedActions": {
                              "description": "Views reaching 25% of the video's length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate = videoP25WatchedActions / videoPlayActions).",
                              "type": "integer"
                            },
                            "videoP50WatchedActions": {
                              "description": "Views reaching 50% of the video's length.",
                              "type": "integer"
                            },
                            "videoP75WatchedActions": {
                              "description": "Views reaching 75% of the video's length.",
                              "type": "integer"
                            },
                            "videoP95WatchedActions": {
                              "description": "Views reaching 95% of the video's length. Sources: Meta `video_p95_watched_actions`, Pinterest `TOTAL_VIDEO_P95_COMBINED`.",
                              "type": "integer"
                            },
                            "videoPlayActions": {
                              "description": "Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads.",
                              "type": "integer"
                            },
                            "videoThruplayWatchedActions": {
                              "description": "ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta `video_thruplay_watched_actions` (Meta only).",
                              "type": "integer"
                            }
                          },
                          "type": "object"
                        },
                        "unsupportedBreakdowns": {
                          "description": "Requested breakdowns this platform cannot break down by (e.g. region on TikTok, any breakdown on Google). Absent when every requested breakdown is supported.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "type": "object"
                    },
                    "backfillPending": {
                      "description": "Always true on this response. Part of the requested range is still being backfilled; retry until the request returns 200.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "backfillPending"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Meta only. Historical data is incomplete and backfill remains pending."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get ad analytics",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_analytics@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "081228a3b4eed7d2721e077ed0628abd2249d6aafb27c4afc52c165b673cdf69"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_adid_analytics",
          "method": "GET",
          "path": "/apis/v1/ads/{adId}/analytics"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_adid_analytics"
      }
    },
    "/apis/v1/ads/{adId}/comments": {
      "get": {
        "description": "Ad Accounts. Read only. Lists the comments on an ad's post, including dark posts that never ran organically, so you can moderate ad engagement. Useful for moderating or analyzing engagement on dark posts (ad creatives that never went live organically). Requires the Ads add-on. ### Ad identifiers The creative's `effective_object_story_id` / `effective_instagram_media_id` ### Meta (Facebook and Instagram)\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_adid_comments",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Which side of the ad to return comments for. Omit to default to the Instagram side when present, else Facebook. Returns ad_not_commentable if the ad has no such placement.",
            "in": "query",
            "name": "placement",
            "required": false,
            "schema": {
              "enum": [
                "facebook",
                "instagram"
              ],
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "TikTok-only start date. Defaults to 30 days before until. Maximum window is 30 days.",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "TikTok-only end date. Defaults to today in UTC.",
            "in": "query",
            "name": "until",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "Pagination cursor from a previous response.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "comments": {
                      "items": {
                        "description": "Normalized comment.",
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "meta": {
                      "properties": {
                        "adId": {
                          "type": "string"
                        },
                        "connectionId": {
                          "description": "The ads connection (adc_...) the object belongs to.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "effectiveStoryId": {
                          "description": "Underlying post ID the comments belong to. effective_object_story_id for the Facebook side, effective_instagram_media_id for the Instagram side.",
                          "type": "string"
                        },
                        "instagramAccountId": {
                          "description": "Instagram-only.",
                          "type": "string"
                        },
                        "instagramPermalink": {
                          "description": "Instagram-only. Public permalink of the boosted IG post (creative.instagram_permalink_url).",
                          "type": "string"
                        },
                        "instagramUserId": {
                          "description": "Instagram-only. The Instagram-scoped business ID that owns the boosted media (creative.instagram_user_id).",
                          "type": "string"
                        },
                        "lastUpdated": {
                          "format": "date-time",
                          "type": "string"
                        },
                        "placement": {
                          "description": "The placement these comments are for, useful when you didn't pass ?placement= and want to know which one you got.",
                          "enum": [
                            "facebook",
                            "instagram"
                          ],
                          "type": "string"
                        },
                        "platform": {
                          "description": "Platform of the comments.",
                          "enum": [
                            "facebook",
                            "instagram",
                            "tiktok"
                          ],
                          "type": "string"
                        },
                        "platformAdId": {
                          "description": "Platform ad ID.",
                          "type": "string"
                        },
                        "since": {
                          "description": "TikTok-only resolved start date.",
                          "format": "date",
                          "type": "string"
                        },
                        "tiktokItemId": {
                          "description": "TikTok-only video item ID from stored ad fields or returned comments. Null does not prevent listing; ad details are not fetched to populate it.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "until": {
                          "description": "TikTok-only resolved end date.",
                          "format": "date",
                          "type": "string"
                        }
                      },
                      "required": [
                        "adId",
                        "lastUpdated",
                        "platform"
                      ],
                      "type": "object"
                    },
                    "pagination": {
                      "properties": {
                        "cursor": {
                          "type": "string"
                        },
                        "hasMore": {
                          "type": "boolean"
                        }
                      },
                      "type": "object"
                    },
                    "status": {
                      "enum": [
                        "success"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "comments",
                    "meta",
                    "pagination",
                    "status"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Comments on the ad."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "List comments on an ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_comments@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "395304e925cae0674ba96072f3d22a6ac0a996629c9a63fa71e6b257d9ad5fb8"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_adid_comments",
          "method": "GET",
          "path": "/apis/v1/ads/{adId}/comments"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_adid_comments"
      }
    },
    "/apis/v1/ads/{adId}/comments/{commentId}": {
      "delete": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Delete your own TikTok ad comment or reply. TikTok must return can_delete=true for the comment. Other users' comments can be hidden instead. Requires Ads access. The ad is resolved within the caller's accessible profiles. ### Identity resolution Unknown identity and video item fields are resolved only when needed for this action, then persisted for reuse. Comment-specific fields take precedence.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "delete_aisa_ads_apis_v1_ads_adid_comments_commentid",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "TikTok comment ID from the ad comment listing.",
            "in": "path",
            "name": "commentId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Start date of the comment lookup window. Defaults to 30 days before until.",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End date of the comment lookup window. Defaults to today in UTC.",
            "in": "query",
            "name": "until",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection, when not sent as a query parameter.",
                    "type": "string"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "commentId": {
                      "description": "ID of the created reply or moderated comment.",
                      "type": "string"
                    },
                    "status": {
                      "enum": [
                        "success"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "commentId",
                    "status"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Comment action completed."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Delete an ad comment",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.delete_ad_comment@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0ba6dede9acb8e04576a956844fb5e9b94d59ee8e9eb2c7349a285958fee23db"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "delete_aisa_ads_apis_v1_ads_adid_comments_commentid",
          "method": "DELETE",
          "path": "/apis/v1/ads/{adId}/comments/{commentId}"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/delete_aisa_ads_apis_v1_ads_adid_comments_commentid"
      }
    },
    "/apis/v1/ads/{adId}/comments/{commentId}/hide": {
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Hide or restore a TikTok ad comment. Send hidden=true to hide it or hidden=false to make it public again. Identity and video item ID are not required; no identity lookup is performed. Requires Ads access. The ad is resolved within the caller's accessible profiles. ### Comment lookup The default search window is the last 30 days.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_adid_comments_commentid_hide",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "TikTok comment ID from the ad comment listing.",
            "in": "path",
            "name": "commentId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Start date of the comment lookup window. Defaults to 30 days before until.",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End date of the comment lookup window. Defaults to today in UTC.",
            "in": "query",
            "name": "until",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "hidden": true
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "hidden": {
                    "description": "True to hide the comment; false to restore it.",
                    "type": "boolean"
                  }
                },
                "required": [
                  "hidden"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "commentId": {
                      "description": "ID of the created reply or moderated comment.",
                      "type": "string"
                    },
                    "hidden": {
                      "description": "The requested visibility state.",
                      "type": "boolean"
                    },
                    "status": {
                      "enum": [
                        "success"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "commentId",
                    "status"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Comment action completed."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Hide or unhide an ad comment",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.hide_ad_comment@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "39380ff6ef0935a09e15d3447889f444131678ec56dd7bec812e6f48912815bb"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_adid_comments_commentid_hide",
          "method": "POST",
          "path": "/apis/v1/ads/{adId}/comments/{commentId}/hide"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_adid_comments_commentid_hide"
      }
    },
    "/apis/v1/ads/{adId}/comments/{commentId}/reply": {
      "post": {
        "description": "Ad Accounts. Changes the ad account without starting or raising spend; audited. Reply to a first-level TikTok ad comment. Replies to replies are rejected. The response commentId identifies the new reply. This operation is not idempotent; do not blindly retry an uncertain response. ### Requirements Requires Ads access. The ad is resolved within the caller's accessible profiles. Requires a TT_USER or CUSTOMIZED_USER identity with comment-management permission.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_adid_comments_commentid_reply",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "TikTok comment ID from the ad comment listing.",
            "in": "path",
            "name": "commentId",
            "required": true,
            "schema": {
              "pattern": "^\\d+$",
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Start date of the comment lookup window. Defaults to 30 days before until.",
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          },
          {
            "description": "End date of the comment lookup window. Defaults to today in UTC.",
            "in": "query",
            "name": "until",
            "required": false,
            "schema": {
              "format": "date",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "text": "Thanks for your question!"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "text": {
                    "description": "Non-empty reply text.",
                    "minLength": 1,
                    "type": "string"
                  }
                },
                "required": [
                  "text"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "commentId": {
                      "description": "ID of the created reply or moderated comment.",
                      "type": "string"
                    },
                    "status": {
                      "enum": [
                        "success"
                      ],
                      "type": "string"
                    }
                  },
                  "required": [
                    "commentId",
                    "status"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Comment action completed."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Reply to an ad comment",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.reply_to_ad_comment@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "4d24a3f8ae8257d02c67f76769cbaf684b8342c71726f1b70eb5862982a01fb0"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_adid_comments_commentid_reply",
          "method": "POST",
          "path": "/apis/v1/ads/{adId}/comments/{commentId}/reply"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_adid_comments_commentid_reply"
      }
    },
    "/apis/v1/ads/{adId}/duplicate": {
      "post": {
        "description": "Ad Campaigns. Can spend money or change spend: needs the ads:spend scope and X-Aisa-Confirm: spend; without the header the request is refused with confirmation_required and nothing is sent. Copies an ad; an active copy starts spending. Copies a single Meta ad, optionally into another ad set, created paused so you can review it before launch. It duplicates the ad via Meta's native `POST /{ad-id}/copies`. The copy is created paused. `adSetId` retargets the copy into another ad set; omitted = the source's own ad set. Sync discovery is triggered automatically (`syncAfter: false` to skip). ### Creative settings\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "post_aisa_ads_apis_v1_ads_adid_duplicate",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          },
          {
            "description": "Passed to the ad platform integration: a retry with the same key returns the first result instead of acting twice. AIsa never retries a write for you.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "maxLength": 191,
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "adSetId": "1234567890",
                "connectionId": "adc_7f3k2m9q",
                "renamePrefix": "example"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "adSetId": {
                    "description": "Destination platform ad set id (defaults to the source's ad set) Must be yours: it is checked through the connection before the request is sent, and an id that is not yours answers not_found.",
                    "type": "string"
                  },
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "renamePrefix": {
                    "description": "Text prepended to the copy's name.",
                    "type": "string"
                  },
                  "renameStrategy": {
                    "description": "Meta's native `rename_strategy` values. An ad has no copied children, so `DEEP_RENAME` and `ONLY_TOP_LEVEL_RENAME` both rename the copy with `renamePrefix` / `renameSuffix`, and `NO_RENAME` keeps the source name.",
                    "enum": [
                      "DEEP_RENAME",
                      "ONLY_TOP_LEVEL_RENAME",
                      "NO_RENAME"
                    ],
                    "type": "string"
                  },
                  "renameSuffix": {
                    "description": "Text appended to the copy's name.",
                    "type": "string"
                  },
                  "reuseSourceCreative": {
                    "default": false,
                    "description": "Point the copy at the source ad's creative object instead of copying it. The copy keeps the same Facebook post and Instagram media, their existing likes, comments and shares, and the full creative setup (text variations included).",
                    "type": "boolean"
                  },
                  "statusOption": {
                    "default": "PAUSED",
                    "enum": [
                      "ACTIVE",
                      "PAUSED",
                      "INHERITED_FROM_SOURCE"
                    ],
                    "type": "string"
                  },
                  "syncAfter": {
                    "default": true,
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "copiedAdId": {
                      "description": "Platform ID of the new ad",
                      "type": "string"
                    },
                    "discovery": {
                      "enum": [
                        "triggered",
                        "skipped",
                        "failed"
                      ],
                      "type": "string"
                    },
                    "raw": {
                      "type": "object"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad duplicated"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Duplicate an ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.duplicate_ad@1",
          "required_scope": "ads:spend",
          "scope_rule": "Can spend money or change spend: needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "5fb5d5b548c2b6b132624ba4584aabd8e672b432285827251447d1dbe14fe25c"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "post_aisa_ads_apis_v1_ads_adid_duplicate",
          "method": "POST",
          "path": "/apis/v1/ads/{adId}/duplicate"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/post_aisa_ads_apis_v1_ads_adid_duplicate"
      }
    },
    "/apis/v1/ads/{adId}/media": {
      "get": {
        "description": "Ad Creatives. Read only. Returns fresh, short-lived download links for every image and video a Meta ad uses, including the original media of a boosted Instagram post. The direct signed URLs cover every video and image asset used by the ad's live creative, normalised across shapes: single image/video carousel Reels/Story (`object_story_spec.video_data`) dynamic creative (`asset_feed_spec`)\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_adid_media",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adId": {
                      "type": "string"
                    },
                    "media": {
                      "items": {
                        "properties": {
                          "index": {
                            "description": "0-based position for carousel children or asset_feed_spec entries.",
                            "type": "integer"
                          },
                          "length": {
                            "description": "Video length in seconds (videos only).",
                            "type": "number"
                          },
                          "thumbnailUrl": {
                            "description": "Video poster URL (videos only).",
                            "type": "string"
                          },
                          "type": {
                            "enum": [
                              "image",
                              "video"
                            ],
                            "type": "string"
                          },
                          "url": {
                            "description": "Direct file URL (signed; short-lived, see description).",
                            "type": "string"
                          },
                          "videoId": {
                            "description": "Meta video id (videos only), reusable as video.id on the create endpoints.",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "platform": {
                      "description": "'facebook' or 'instagram'. Only Meta is supported for now.",
                      "type": "string"
                    },
                    "synced": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Media assets"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Direct video and image URLs for an ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_media@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "0793992d6a98ac3483b836745343b576e3a449d5e86d36528cd03fcc714ba0ad"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_adid_media",
          "method": "GET",
          "path": "/apis/v1/ads/{adId}/media"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_adid_media"
      }
    },
    "/apis/v1/ads/{adId}/preview": {
      "get": {
        "description": "Ad Creatives. Read only. Shows how an existing Meta ad looks in each placement, as embeddable previews. Renders an EXISTING ad per placement via Meta's `/{ad_id}/previews`. Each preview is an HTML `` snippet embeddable directly. Unknown `formats` values return Meta's 400 verbatim. Meta ads that are not synced yet.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_adid_preview",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Comma-separated Meta ad_format values (max 10), one preview per format. Defaults to DESKTOP_FEED_STANDARD.",
            "in": "query",
            "name": "formats",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adId": {
                      "type": "string"
                    },
                    "previews": {
                      "items": {
                        "properties": {
                          "format": {
                            "type": "string"
                          },
                          "html": {
                            "description": "Meta's snippet; null when Meta returned no preview for the format.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "synced": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Rendered previews"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Render previews of an existing ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_previews@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "c2e6ef1c626f5c934746075e68497002034be9ff1bebe587f72c0ed5415880bf"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_adid_preview",
          "method": "GET",
          "path": "/apis/v1/ads/{adId}/preview"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_adid_preview"
      }
    },
    "/apis/v1/ads/{adId}/review": {
      "get": {
        "description": "Ad Campaigns. Read only. Shows whether the platform approved an ad, where it may not deliver, and every rejection reason, without re-enabling a paused ad. It reads the ad's review verdict from the platform now, including every rejection reason with TikTok's suggestion and the piece of content it refers to. It is read-only, so it works on a paused ad without re-enabling it. Supported on TikTok, Google and Meta.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_adid_review",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "platform": {
                      "type": "string"
                    },
                    "platformAdId": {
                      "type": "string"
                    },
                    "review": {
                      "properties": {
                        "approvalStatus": {
                          "description": "Google only. ad_group_ad.policy_summary.approval_status, verbatim.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "approved": {
                          "description": "TikTok `is_approved`. Google and Meta: derived from the platform status (see the description).",
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "forbiddenAges": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "forbiddenLocations": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "forbiddenOperatingSystems": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "forbiddenPlacements": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "issues": {
                          "description": "Meta only. The Ad's `issues_info` objects (`error_code`, `error_message`, `error_summary`, `error_type`, `level`), verbatim.",
                          "items": {
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "policyTopics": {
                          "description": "Google only. ad_group_ad.policy_summary.policy_topic_entries.",
                          "items": {
                            "properties": {
                              "constraints": {
                                "description": "Google's PolicyTopicConstraint objects, verbatim.",
                                "items": {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "evidences": {
                                "description": "Google's PolicyTopicEvidence objects, verbatim.",
                                "items": {
                                  "additionalProperties": true,
                                  "type": "object"
                                },
                                "type": "array"
                              },
                              "topic": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "type": {
                                "description": "PROHIBITED, LIMITED, FULLY_LIMITED, DESCRIPTIVE, BROADENING, AREA_OF_INTEREST_ONLY.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "readAt": {
                          "description": "When the verdict was read from the platform.",
                          "format": "date-time",
                          "type": "string"
                        },
                        "rejections": {
                          "description": "One entry per rejected piece of content (TikTok `reject_info`). Empty when the ad was approved.",
                          "items": {
                            "properties": {
                              "content": {
                                "additionalProperties": true,
                                "description": "The content TikTok reviewed.",
                                "type": [
                                  "object",
                                  "null"
                                ]
                              },
                              "forbiddenAges": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "forbiddenLocations": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "forbiddenPlacements": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "reasons": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "suggestion": {
                                "description": "TikTok's advice for fixing the rejection.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "reviewFeedback": {
                          "description": "Meta only. The Ad's `ad_review_feedback`, verbatim. Both maps are empty when Meta returned no feedback (approved or in-review ad).",
                          "properties": {
                            "global": {
                              "additionalProperties": {
                                "type": "string"
                              },
                              "description": "Meta `global`: policy or reason -> Meta's explanation.",
                              "type": "object"
                            },
                            "placementSpecific": {
                              "additionalProperties": {
                                "additionalProperties": true,
                                "type": "object"
                              },
                              "description": "Meta `placement_specific`: placement (facebook, instagram, ...) -> reason -> Meta's explanation.",
                              "type": "object"
                            }
                          },
                          "type": "object"
                        },
                        "reviewStatus": {
                          "description": "TikTok `review_status`, verbatim: ALL_AVAILABLE (approved everywhere), PART_AVAILABLE (approved for part of the targeting), UNAVAILABLE (rejected). Google: `review_status`. Meta: the ad's `effective_status`.",
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": "object"
                    },
                    "synced": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The review verdict"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Read the platform's review verdict for an ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_review@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "6a945b4542300d5b7476e4d4dbb9fed1b1cb54fea743c2fd8782d00733c57cd3"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_adid_review",
          "method": "GET",
          "path": "/apis/v1/ads/{adId}/review"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_adid_review"
      }
    },
    "/apis/v1/ads/{adId}/status": {
      "put": {
        "description": "Ad Campaigns. A pause needs ads:write. A change to active turns delivery on: it needs ads:spend and X-Aisa-Confirm: spend. Pauses or resumes a single ad without touching its ad set, campaign or sibling ads. ### What it flips Ad-scoped pause/resume flips ONLY this ad's own switch, never its parent ad set or campaign, so sibling ads keep running: Meta `configured_status` TikTok `operation_status` Google ad group ad status LinkedIn creative Pinterest ad Reddit ad `configured_status`\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "put_aisa_ads_apis_v1_ads_adid_status",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          },
          {
            "description": "Required with the value \"spend\" when the request can spend money or change spend. Without it the request is refused with 409 confirmation_required, which describes what would happen; nothing is sent to the ad platform.",
            "in": "header",
            "name": "X-Aisa-Confirm",
            "required": false,
            "schema": {
              "enum": [
                "spend"
              ],
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "status": "active"
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "status": {
                    "enum": [
                      "active",
                      "paused"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "status"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "configuredStatus": {
                      "description": "The ad's own on/off switch (`ACTIVE` / `PAUSED`), re-read from the platform after the write. Null where the platform exposes no per-ad switch (X) or the read-back failed and the platform does not store one.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "message": {
                      "description": "Human-readable summary (present only when skipped), e.g. \"No change: the ad's own switch is already off\"",
                      "type": "string"
                    },
                    "skipped": {
                      "description": "1 when skipped (terminal status, or the ad's own switch already in the target state), else 0",
                      "type": "integer"
                    },
                    "status": {
                      "description": "The ad's delivery status after the call, as the platform reports it when it can be read back (e.g. `paused` for an ad switched on under a paused campaign)",
                      "type": "string"
                    },
                    "updated": {
                      "description": "1 when the switch was written, 0 when skipped",
                      "type": "integer"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Ad status updated (or skipped when no change was needed)"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Pause or resume a single ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_status@1",
          "required_scope": "ads:write",
          "scope_rule": "Pausing needs ads:write; turning delivery on needs ads:spend and X-Aisa-Confirm: spend."
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "62016c5cb51c9a6e4a322e7f6b9e5b2ea4159675826332cd47638b65724d3b16"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "put_aisa_ads_apis_v1_ads_adid_status",
          "method": "PUT",
          "path": "/apis/v1/ads/{adId}/status"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/put_aisa_ads_apis_v1_ads_adid_status"
      }
    },
    "/apis/v1/ads/{adId}/tiktok-smart-plus-review": {
      "get": {
        "description": "Ad Campaigns. Read only. Shows which Spark post, video or carousel of an Upgraded Smart+ ad TikTok approved or rejected, with every rejection reason, keyed by the TikTok post id for a Spark post. It reads TikTok's `/smart_plus/ad/review_info/` live (read-only, works on a paused ad) for the Smart+ ad that holds `adId`. It returns the ad-level verdict plus one entry per creative. ### Which ad is read\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_adid_tiktok_smart_plus_review",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "adId": {
                      "type": "string"
                    },
                    "materials": {
                      "description": "One entry per creative TikTok reviewed (`material_review_infos`).",
                      "items": {
                        "description": "The verdict of one creative of a Smart+ ad (`material_review_infos`).",
                        "properties": {
                          "adMaterialId": {
                            "description": "TikTok `ad_material_id` of the creative inside this ad.",
                            "type": "string"
                          },
                          "materialType": {
                            "description": "Null for a creative TikTok added on its own or a carousel image.",
                            "enum": [
                              "spark_post",
                              "video",
                              "carousel",
                              "catalog_carousel",
                              null
                            ],
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "operationStatus": {
                            "description": "TikTok `material_operation_status`: ENABLE or DISABLE.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "passedLocations": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "rawReviewStatus": {
                            "description": "TikTok `review_status`, verbatim.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "rejectReasons": {
                            "description": "Every distinct reason across `rejections`. Empty when approved.",
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "rejections": {
                            "items": {
                              "additionalProperties": true,
                              "description": "One TikTok `reject_info` entry.",
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "reviewStatus": {
                            "description": "TikTok `review_status` normalized: ALL_AVAILABLE -> approved, PART_AVAILABLE -> partially_approved (delivers in part of the targeted locations), UNAVAILABLE -> rejected, anything else or missing -> unknown (see `rawReviewStatus`).",
                            "enum": [
                              "approved",
                              "partially_approved",
                              "rejected",
                              "unknown"
                            ],
                            "type": "string"
                          },
                          "tiktokItemId": {
                            "description": "The TikTok post id when the creative is a Spark post.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "videoId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "platform": {
                      "enum": [
                        "tiktok"
                      ],
                      "type": "string"
                    },
                    "platformAdId": {
                      "type": "string"
                    },
                    "readAt": {
                      "description": "When the verdict was read from TikTok.",
                      "format": "date-time",
                      "type": "string"
                    },
                    "review": {
                      "description": "The ad-level verdict of a Smart+ ad (`smart_plus_ad_review_infos`). Null when TikTok returned none.",
                      "properties": {
                        "appealRejectReasons": {
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "appealStatus": {
                          "description": "TikTok `appeal_status`, verbatim: NOT_APPEALED, APPEALING, APPEAL_SUCCESSFUL, APPEAL_FAILED, APPEAL_DONE.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "passedLocations": {
                          "description": "Location codes that passed the review.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "rawReviewStatus": {
                          "description": "TikTok `review_status`, verbatim.",
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "rejectReasons": {
                          "description": "Every distinct reason across `rejections`.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "rejections": {
                          "items": {
                            "description": "One TikTok `reject_info` entry.",
                            "properties": {
                              "content": {
                                "additionalProperties": true,
                                "description": "The content TikTok rejected.",
                                "type": [
                                  "object",
                                  "null"
                                ]
                              },
                              "forbiddenAges": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "forbiddenLocations": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "forbiddenPlacements": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "reasons": {
                                "items": {
                                  "type": "string"
                                },
                                "type": "array"
                              },
                              "suggestion": {
                                "description": "TikTok's advice for fixing the rejection.",
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "type": "object"
                          },
                          "type": "array"
                        },
                        "reviewStatus": {
                          "description": "TikTok `review_status` normalized: ALL_AVAILABLE -> approved, PART_AVAILABLE -> partially_approved (delivers in part of the targeted locations), UNAVAILABLE -> rejected, anything else or missing -> unknown (see `rawReviewStatus`).",
                          "enum": [
                            "approved",
                            "partially_approved",
                            "rejected",
                            "unknown"
                          ],
                          "type": "string"
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "smartPlusAdId": {
                      "description": "The TikTok Smart+ ad whose review this is.",
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The Smart+ ad's review verdict per creative"
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Review status of each creative in a TikTok Smart+ ad",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_tik_tok_smart_plus_ad_review@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "85dac6bed85ce6b849a1c3a6a244def57e620d2b667a2a9591312c10b9c094df"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_adid_tiktok_smart_plus_review",
          "method": "GET",
          "path": "/apis/v1/ads/{adId}/tiktok-smart-plus-review"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_adid_tiktok_smart_plus_review"
      }
    },
    "/apis/v1/ads/{adId}/tracking-tags": {
      "get": {
        "description": "Tracking Tags. Read only. Shows the tracking parameters added to an ad's click URLs, such as UTM tags (not pixels). Unified read of the platform's native click-URL tracking params. Meta (facebook/instagram): the creative's `url_tags` (and template_url_spec). Google (googleads): the campaign's `trackingUrlTemplate` + `finalUrlSuffix`.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "get_aisa_ads_apis_v1_ads_adid_tracking_tags",
        "parameters": [
          {
            "description": "Ad id (hex _id, platformAdId, or effective story/media id).",
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "customValueParameters": {
                      "description": "LinkedIn.",
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "dynamicValueParameters": {
                      "description": "LinkedIn.",
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "finalUrlSuffix": {
                      "description": "Google.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "level": {
                      "enum": [
                        "creative",
                        "campaign"
                      ],
                      "type": "string"
                    },
                    "platform": {
                      "type": "string"
                    },
                    "templateUrlSpec": {
                      "description": "Meta: third-party click-tracking template (Dynamic Ads).",
                      "type": [
                        "object",
                        "null"
                      ]
                    },
                    "trackingUrlTemplate": {
                      "description": "Google.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "urlTags": {
                      "description": "Meta: &-joined click-URL params.",
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Tracking tags for the ad's platform (shape varies by platform)."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Get ad tracking tags",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.get_ad_tracking_tags@1",
          "required_scope": "ads:read"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "16c2b8fbf26fbaac03f596483f0a7a9ef799c415d3c47242d3ff51b432ec3ac0"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "get_aisa_ads_apis_v1_ads_adid_tracking_tags",
          "method": "GET",
          "path": "/apis/v1/ads/{adId}/tracking-tags"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/get_aisa_ads_apis_v1_ads_adid_tracking_tags"
      },
      "patch": {
        "description": "Tracking Tags. Changes the ad account without starting or raising spend; audited. Sets the tracking parameters added to an ad's click URLs, such as UTM tags, without rebuilding the rest of the ad. Send only the fields for the ad's platform. ### Meta Send `urlTags` (array of {key,value}). Meta creatives are immutable, so this rebuilds the creative and repoints the ad.\n\n<!-- aisa-pricing:start -->\n当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。\n<!-- aisa-pricing:end -->",
        "operationId": "patch_aisa_ads_apis_v1_ads_adid_tracking_tags",
        "parameters": [
          {
            "in": "path",
            "name": "adId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The ads connection (adc_...) the request runs on: one of yours, from GET /apis/v1/ads/connections. On a request with a JSON body it may be sent as a top-level body member instead.",
            "in": "query",
            "name": "connectionId",
            "required": true,
            "schema": {
              "pattern": "^adc_[0-9A-Za-z]+$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "connectionId": "adc_7f3k2m9q",
                "creative": {
                  "body": "example",
                  "callToAction": "example",
                  "headline": "example",
                  "imageUrl": "https://example.com/landing",
                  "linkUrl": "https://example.com/landing"
                },
                "customValueParameters": {}
              },
              "schema": {
                "additionalProperties": true,
                "properties": {
                  "connectionId": {
                    "description": "The ads connection (adc_...), when not sent as the connectionId query parameter.",
                    "pattern": "^adc_[0-9A-Za-z]+$",
                    "type": "string"
                  },
                  "creative": {
                    "description": "Meta only. OPTIONAL: omit to preserve the existing creative verbatim (default). Provide it only to rebuild the creative explicitly, or for creatives whose object_story_spec Meta strips.",
                    "properties": {
                      "body": {
                        "type": "string"
                      },
                      "callToAction": {
                        "type": "string"
                      },
                      "headline": {
                        "type": "string"
                      },
                      "imageUrl": {
                        "format": "uri",
                        "type": "string"
                      },
                      "linkUrl": {
                        "format": "uri",
                        "type": "string"
                      },
                      "videoUrl": {
                        "format": "uri",
                        "type": "string"
                      }
                    },
                    "required": [
                      "body",
                      "callToAction",
                      "headline",
                      "imageUrl",
                      "linkUrl"
                    ],
                    "type": "object"
                  },
                  "customValueParameters": {
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "LinkedIn only. key -> static value.",
                    "type": "object"
                  },
                  "dynamicValueParameters": {
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "LinkedIn only. key -> dynamic value enum (CAMPAIGN_ID, CAMPAIGN_NAME, CREATIVE_ID, ...).",
                    "type": "object"
                  },
                  "finalUrlSuffix": {
                    "description": "Google only. Parse-only key=value params.",
                    "type": "string"
                  },
                  "trackingUrlTemplate": {
                    "description": "Google only. Full tracking template (must contain {lpurl}).",
                    "type": "string"
                  },
                  "urlTags": {
                    "description": "Meta only. Click-URL params appended to a freshly-rebuilt creative. Meta dynamic macros ({{ad.id}}, {{campaign.id}}, {{placement}}, ...) are sent through unescaped so Meta expands them; every other character is percent-encoded.",
                    "items": {
                      "properties": {
                        "key": {
                          "type": "string"
                        },
                        "value": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "key",
                        "value"
                      ],
                      "type": "object"
                    },
                    "type": "array"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "properties": {
                    "platform": {
                      "type": "string"
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "The tags as they now stand, in the same shape the GET on this path returns: `platform` plus the fields that platform supports."
          },
          "default": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "properties": {
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "details": {
                          "additionalProperties": {},
                          "type": [
                            "object",
                            "null"
                          ]
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "param": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryHint": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "retryable": {
                          "type": [
                            "boolean",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "type": [
                        "object",
                        "null"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Error. The code field is stable; see the error catalog."
          }
        },
        "summary": "Set ad tracking tags",
        "x-aisa-capabilities": {
          "idempotency": "Idempotency-Key",
          "max_price": "X-AISA-Max-Price-USD",
          "quote": {
            "reason": "not_quoted",
            "supported": false
          },
          "capability": "ads.update_ad_tracking_tags@1",
          "required_scope": "ads:write"
        },
        "x-aisa-contract-source": "handler",
        "x-aisa-identity-source": "derived",
        "x-aisa-pricing": {
          "description": "Ads operations are free. Ad spend is billed by the ad platform to the connected ad account, never by AIsa.",
          "kind": "no_customer_charge"
        },
        "x-aisa-revision": {
          "handler_contract_hash": "79f2cd2ac71bb39b896b2c46ac538783736274a9e7970b73eb2d6e1ebe397757"
        },
        "x-aisa-status": "enabled",
        "x-aisa-validation": "runtime",
        "x-aisa-catalog-id": "aisa-ads",
        "x-aisa-runtime-operation": {
          "operation_id": "patch_aisa_ads_apis_v1_ads_adid_tracking_tags",
          "method": "PATCH",
          "path": "/apis/v1/ads/{adId}/tracking-tags"
        },
        "x-aisa-docs-url": "https://aisa.one/docs/api-reference/aisa-ads/patch_aisa_ads_apis_v1_ads_adid_tracking_tags"
      }
    }
  }
}
