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

> ## Agent Instructions
> - Base URLs: models `https://api.aisa.one/v1` (Gemini GenerateContent: `https://api.aisa.one/v1beta`); data APIs `https://api.aisa.one/apis/v1`. The `servers` of each operation in https://aisa.one/openapi.yaml is authoritative.
> - Auth: `Authorization: Bearer $AISA_API_KEY`. Never print, log, or commit the key.
> - MCP (preferred for agents): `https://mcp.aisa.one/mcp`, signed in with OAuth, so there is no key to paste.
> - Agent Skill: `npx skills add AIsa-team/agent-skills --skill aisa`. Fallback with the AIsa CLI: `aisa skills install aisa`.
> - Spending: docs, https://aisa.one/models, https://aisa.one/api, `/v1/models`, and MCP `search`, `list_categories`, `get_details`, `batch_quote`, and the `account` operation are free. Quote the exact calls before running them (MCP `batch_quote`, CLI `aisa quote --json`). If the quote reports `auto_execute_eligible: true`, run it unless the user set a tighter limit or asked only for a quote. Otherwise, tell the user in one message the planned calls, the quoted price, and a total USD budget for the task, then wait for approval. Direct HTTP calls follow the stricter rule at https://aisa.one/docs/get-started/cli.md#direct-http-fallback. Do not make paid calls to test availability. Full rule: https://aisa.one/llms.txt

# Get campaign tree

> 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.

<!-- aisa-pricing:start -->
当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。
<!-- aisa-pricing:end -->

## 请求规范

* **方法与路径:** GET /apis/v1/ads/tree
* **可用状态:** enabled
* **请求 URL 模板:** `https://api.aisa.one/apis/v1/ads/tree`
* **connectionId:** query; 必填
* **page:** query; 可选
* **limit:** query; 可选
* **source:** query; 可选
* **platform:** query; 可选
* **status:** query; 可选
* **adAccountId:** query; 可选
* **pageId:** query; 可选
* **campaignId:** query; 可选
* **updatedSince:** query; 可选
* **search:** query; 可选
* **fromDate:** query; 可选
* **toDate:** query; 可选
* **hasDelivery:** query; 可选
* **minSpend:** query; 可选
* **sort:** query; 可选
* **timeIncrement:** query; 可选
* **dailyLevel:** query; 可选
* **compare:** query; 可选
* **results:** query; 可选
* **Runtime 事实版本:** fe60122939c67dc98a3a6ac6b97bd5c326b526105150c8959304dd2160d4dd09

[完整 OpenAPI 定义](https://aisa.one/docs/reference-contracts/zh/aisa-ads.json)

有效请求与价格声明（包括认证和引用的 schema）：

```json theme={null}
{
  "operationId": "get_aisa_ads_apis_v1_ads_tree",
  "method": "GET",
  "path": "/apis/v1/ads/tree",
  "servers": [
    {
      "url": "https://api.aisa.one"
    }
  ],
  "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"
      }
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "x-aisa-status": "enabled",
  "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"
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "scheme": "bearer",
        "type": "http"
      }
    }
  }
}
```

## 费用与请求规则

当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。

公开参考值不是你的账户报价或最终扣费。对于支持 X-AISA-Cost-Mode: quote 的接口，执行前请针对完整请求获取免费报价；执行后通过响应费用元数据和 Usage Logs 核对结算费用。1 USD 等于 1,000,000 个整数 micro-USD。


## OpenAPI

````yaml reference-contracts/zh/aisa-ads.json GET /apis/v1/ads/tree
openapi: 3.1.0
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
    display_plan: payg
    payg: 1
    similarweb_payg: 1
    team: 1
    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
        display_plan: payg
        payg: 1
        similarweb_payg: 1
        team: 1
        version: e70a0959cd1b93b84ae16dffd7a538273ddb9c1d46277b82823c37ff1b6bc0fb
      x-aisa-capabilities:
        idempotency: Idempotency-Key
        max_price: X-AISA-Max-Price-USD
        quote:
          header: X-AISA-Cost-Mode
          value: quote
servers:
  - url: https://api.aisa.one
security:
  - bearerAuth: []
paths:
  /apis/v1/ads/tree:
    get:
      summary: Get campaign tree
      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.


        <!-- aisa-pricing:start -->

        当前未提供请求参考价格；请使用接口支持的报价功能确认费用。 最终费用以账户适用价格及实际结算为准。

        <!-- 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.
components:
  securitySchemes:
    bearerAuth:
      scheme: bearer
      type: http

````

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