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

# Get Apple Ads report

> Qonversion cohort metrics joined with Apple Ads report data (spend,
impressions, taps, installs) for one level: campaigns, ad groups, or
keywords. Each row carries a `qonversion` block (cohort outcomes:
users, trials, revenue, ARPU/ARPPU), an `apple` block (spend and
delivery metrics, including `avg_cpa` — Apple's average cost per
tap-through install), and a derived `roas` ratio.

**CPA is not CAC.** `apple.avg_cpa` is the cost of an install as Apple
reports it. The cost of acquiring a paying user is `windows.<code>.cac`
(window spend / payers — `spend_closed` in the mature reading, `spend`
in the growing one), available only when `windows` is requested. The
two differ by the whole install-to-payer funnel; never quote one as
the other.

**Availability**: available to accounts with Apple Ads enabled; other
accounts receive `404`. Contact support to enable Apple Ads.

**Data markers**: `apple` is `null` for rows without Apple data;
`partial_sources` lists Apple data sources not included (empty when
complete); `meta.partial_scope` counts campaigns without Apple data.
Qonversion metrics are always complete.

**Semantics**: revenue is cohort revenue cumulative to date (only the
install date is bounded by `[from, to]`); `roas` is a ratio, not a
percentage, and not a closed ratio — revenue keeps accruing while
spend is bounded by the period. `meta.semantics` in every response
defines each metric.

**Reporting basis**: `revenue_type` selects the revenue behind the
derived metrics (`roas`, `arpu`, `arppu`, and `windows.*.revenue` /
`windows.*.roas`) — `gross` (store-billed, default) or `net`
(proceeds after store commission, and after store tax where the store
reports it). Rows always carry both `revenue_gross` and
`revenue_net`, so `revenue_type` never removes a field;
`windows.*.cac` and `windows.*.cost_per_trial` depend on spend only.
`currency` converts every monetary value at one midpoint rate for the
period (see `meta.currency_conversion`). If no exchange rate is
available for the period, values are in USD: `currency` is `USD` and
`meta.rate_unavailable_for` holds the requested code. Both
`currency` and `revenue_type` are echoed at the top level.

**Cohort windows** (optional, `windows=`): pass
`windows=d7,d30,lifetime` and each row also carries a `windows` block
of per-window cohort metrics (installs, trials, payers, revenue,
`roas`, `cac`, `cost_per_trial`). See the `windows` parameter and
`meta.windows`.

**Cohort window modes** (`windows_mode=`): `growing` is the to-date
cohort reading — every install of the period, events up to today, and
the row's Apple spend for the period as the denominator; its values
change until the period matures. `mature` covers matured install
dates only — dates past the window length plus
`maturation_buffer_days` — so its ratios over that closed date range
are comparable across rows and periods of different ages (`lifetime`
can still change as cumulative revenue accrues). Both modes share
`V4AnalyticsAppleAdsWindow`; the growing one adds `mode`, `through`,
and `spend` and omits `spend_closed`. When `windows_mode` is omitted,
the server applies its default mode; send `windows_mode` explicitly
when the reading matters. If you omit it, check `meta.windows.mode`
(or a window's own `mode: growing`) for the reading served. If
`meta.windows.mode` is absent, the response uses the mature reading.

**Pagination**: this endpoint uses `limit`/`offset` pagination with a
`pagination` block, not cursors. Offsets are stable within a sort
order.

**Rate limits**: the report and series endpoints are rate limited. A
`429` response includes `Retry-After`; wait that long before
retrying.




## OpenAPI

````yaml /api-reference/rest-api-v4.yaml get /analytics/apple-ads/report
openapi: 3.0.3
info:
  title: Qonversion REST API v4
  version: '4.0'
  description: >-
    Qonversion REST API v4 follows REST standards. It has predictable
    resource-oriented URLs, accepts JSON-encoded request bodies, returns
    JSON-encoded responses, and uses standard HTTP response codes,
    authentication, and verbs.
servers:
  - url: https://api.qonversion.io/v4
    description: Production
security:
  - secretAuth: []
tags:
  - name: Users
    description: Retrieve Qonversion users
  - name: User Properties
    description: Manage user-level attributes
  - name: Identities
    description: Link Qonversion users to your own auth IDs
  - name: Entitlements
    description: Entitlement definitions and user grants
  - name: Purchases
    description: A user's purchase history
  - name: Products
    description: Products configured in the Qonversion dashboard
  - name: Remote Configurations
    description: Server-driven configuration payloads and targeting delivered to the SDK
  - name: Customers
    description: Aggregated customer records, properties, permissions, and metrics
  - name: Segments
    description: Dynamic and system segments of users
  - name: Experiments
    description: Paywall and offering A/B experiments
  - name: Screens
    description: No-code paywall screens — CRUD, publish, analytics
  - name: Analytics
    description: Charts, cards, cohorts, LTV, and insights
  - name: Apple Ads
    description: Apple Ads reports, daily series, and connection status
  - name: Exports
    description: Asynchronous data exports
  - name: Events
    description: Event catalog
  - name: Scheduled Reports
    description: Recurring reports delivered to external destinations
  - name: Integrations
    description: Third-party integrations configuration
  - name: Automations
    description: Event-driven automations
  - name: Project Settings
    description: Project-level configuration, secret, and store credentials
paths:
  /analytics/apple-ads/report:
    get:
      tags:
        - Apple Ads
      summary: Get Apple Ads report
      description: |
        Qonversion cohort metrics joined with Apple Ads report data (spend,
        impressions, taps, installs) for one level: campaigns, ad groups, or
        keywords. Each row carries a `qonversion` block (cohort outcomes:
        users, trials, revenue, ARPU/ARPPU), an `apple` block (spend and
        delivery metrics, including `avg_cpa` — Apple's average cost per
        tap-through install), and a derived `roas` ratio.

        **CPA is not CAC.** `apple.avg_cpa` is the cost of an install as Apple
        reports it. The cost of acquiring a paying user is `windows.<code>.cac`
        (window spend / payers — `spend_closed` in the mature reading, `spend`
        in the growing one), available only when `windows` is requested. The
        two differ by the whole install-to-payer funnel; never quote one as
        the other.

        **Availability**: available to accounts with Apple Ads enabled; other
        accounts receive `404`. Contact support to enable Apple Ads.

        **Data markers**: `apple` is `null` for rows without Apple data;
        `partial_sources` lists Apple data sources not included (empty when
        complete); `meta.partial_scope` counts campaigns without Apple data.
        Qonversion metrics are always complete.

        **Semantics**: revenue is cohort revenue cumulative to date (only the
        install date is bounded by `[from, to]`); `roas` is a ratio, not a
        percentage, and not a closed ratio — revenue keeps accruing while
        spend is bounded by the period. `meta.semantics` in every response
        defines each metric.

        **Reporting basis**: `revenue_type` selects the revenue behind the
        derived metrics (`roas`, `arpu`, `arppu`, and `windows.*.revenue` /
        `windows.*.roas`) — `gross` (store-billed, default) or `net`
        (proceeds after store commission, and after store tax where the store
        reports it). Rows always carry both `revenue_gross` and
        `revenue_net`, so `revenue_type` never removes a field;
        `windows.*.cac` and `windows.*.cost_per_trial` depend on spend only.
        `currency` converts every monetary value at one midpoint rate for the
        period (see `meta.currency_conversion`). If no exchange rate is
        available for the period, values are in USD: `currency` is `USD` and
        `meta.rate_unavailable_for` holds the requested code. Both
        `currency` and `revenue_type` are echoed at the top level.

        **Cohort windows** (optional, `windows=`): pass
        `windows=d7,d30,lifetime` and each row also carries a `windows` block
        of per-window cohort metrics (installs, trials, payers, revenue,
        `roas`, `cac`, `cost_per_trial`). See the `windows` parameter and
        `meta.windows`.

        **Cohort window modes** (`windows_mode=`): `growing` is the to-date
        cohort reading — every install of the period, events up to today, and
        the row's Apple spend for the period as the denominator; its values
        change until the period matures. `mature` covers matured install
        dates only — dates past the window length plus
        `maturation_buffer_days` — so its ratios over that closed date range
        are comparable across rows and periods of different ages (`lifetime`
        can still change as cumulative revenue accrues). Both modes share
        `V4AnalyticsAppleAdsWindow`; the growing one adds `mode`, `through`,
        and `spend` and omits `spend_closed`. When `windows_mode` is omitted,
        the server applies its default mode; send `windows_mode` explicitly
        when the reading matters. If you omit it, check `meta.windows.mode`
        (or a window's own `mode: growing`) for the reading served. If
        `meta.windows.mode` is absent, the response uses the mature reading.

        **Pagination**: this endpoint uses `limit`/`offset` pagination with a
        `pagination` block, not cursors. Offsets are stable within a sort
        order.

        **Rate limits**: the report and series endpoints are rate limited. A
        `429` response includes `Retry-After`; wait that long before
        retrying.
      operationId: v4GetAnalyticsAppleAdsReport
      parameters:
        - name: level
          in: query
          required: false
          description: Hierarchy level of the report rows.
          schema:
            type: string
            enum:
              - campaigns
              - groups
              - keywords
            default: campaigns
        - name: from
          in: query
          required: true
          description: >-
            Cohort window start (unix seconds, UTC). Installs attributed to
            Apple Ads within `[from, to]` form the cohort.
          schema:
            type: integer
            format: int64
        - name: to
          in: query
          required: true
          description: Cohort window end (unix seconds, UTC).
          schema:
            type: integer
            format: int64
        - name: environment
          in: query
          required: false
          description: >-
            Environment: `0` = sandbox, `1` = production. Defaults to production
            when omitted.
          schema:
            type: integer
            enum:
              - 0
              - 1
            default: 1
        - name: revenue_type
          in: query
          required: false
          description: >-
            Revenue basis for the derived metrics: `gross` (store-billed amount)
            or `net` (proceeds — after store commission, and after tax where the
            store reports it). Affects `roas`, `arpu`, `arppu`, the
            `revenue`/`refunds` sort keys, and `windows.*.revenue` /
            `windows.*.roas`. It does not affect `windows.*.cac` or
            `windows.*.cost_per_trial` (both spend-only), and it never removes a
            field — `qonversion.revenue_gross` and `qonversion.revenue_net` are
            always both present. Echoed back as the top-level `revenue_type`.
          schema:
            type: string
            enum:
              - gross
              - net
            default: gross
        - name: currency
          in: query
          required: false
          description: >-
            ISO 4217 code (uppercase, exactly three letters — `eur` returns
            `400`) for the monetary values. Values are converted from USD at one
            midpoint rate for the whole `[from, to]` period, reported in
            `meta.currency_conversion` (`rate`, `rate_date`, `method:
            single_midpoint_rate`). The rate is the one for the period's
            midpoint date, or the latest one before it.

            If no exchange rate is available for the period, values are in USD:
            `currency` is `USD` and `meta.rate_unavailable_for` holds the
            requested code. Read the top-level `currency` to know which currency
            the values are in.

            `min_spend` is compared against the converted spend, so it is in
            this currency too.
          schema:
            type: string
            pattern: ^[A-Z]{3}$
            default: USD
            example: EUR
        - name: sort
          in: query
          required: false
          description: >-
            Sort key — one of the wire metric names: spend, revenue, roas,
            installs, impressions, taps, ttr, cpa, cpt, cpm, new_downloads,
            redownloads, users, trials, trials_converted, paying, paying_weekly,
            paying_monthly, paying_annual, paying_other, in_apps,
            direct_subscriptions, subscription_starters, cost_per_subscription,
            cost_per_trial, arpu, arppu, refunds, user_to_trial,
            user_to_subscription, trial_to_paid. Note the sort keys are the
            SHORT metric names (cpa/cpt/cpm sort the avg_cpa/avg_cpt/avg_cpm
            columns; trials sorts trials_started; paying sorts
            unique_paying_users; subscription_starters sorts
            unique_subscription_starters; the four paying_<duration> keys sort
            `qonversion.unique_paying_users_by_duration.<bucket>`).

            A window sort key is also accepted; it additionally depends on the
            requested windows: `window_roas_<code>` / `window_cac_<code>` (e.g.
            `window_roas_d7`) orders rows by that window's ratio in the reading
            served (see `windows_mode` and `meta.windows.mode`): in the
            `growing` reading the ratio is to-date and not closed; in the
            `mature` reading it is the ratio over the closed date range (for
            `lifetime` not necessarily final, as cumulative revenue can still
            accrue). The key is rejected with 400 unless the same `<code>` is
            listed in `windows`. Unknown values are rejected with 400.
          schema:
            type: string
            default: spend
            oneOf:
              - enum:
                  - spend
                  - revenue
                  - roas
                  - installs
                  - impressions
                  - taps
                  - ttr
                  - cpa
                  - cpt
                  - cpm
                  - new_downloads
                  - redownloads
                  - users
                  - trials
                  - trials_converted
                  - paying
                  - paying_weekly
                  - paying_monthly
                  - paying_annual
                  - paying_other
                  - in_apps
                  - direct_subscriptions
                  - subscription_starters
                  - cost_per_subscription
                  - cost_per_trial
                  - arpu
                  - arppu
                  - refunds
                  - user_to_trial
                  - user_to_subscription
                  - trial_to_paid
              - type: string
                pattern: >-
                  ^window_(roas|cac)_(d0|d3|d7|d14|d30|d60|d90|d180|d365|lifetime)$
        - name: sort_dir
          in: query
          required: false
          description: Sort direction.
          schema:
            type: string
            enum:
              - asc
              - desc
            default: desc
        - name: q
          in: query
          required: false
          description: >-
            Case-insensitive substring match over the level entity name and id,
            applied before pagination. Narrows table rows only — `total` and
            `unallocated` stay whole-report.
          schema:
            type: string
            maxLength: 64
        - name: min_spend
          in: query
          required: false
          description: >-
            Keep only rows whose Apple spend is at least this threshold,
            compared against the converted `apple.spend` in the response
            `currency`. Rows without spend data never match and are counted in
            `pagination.rows_without_spend_hidden`.
          schema:
            type: number
            minimum: 0
        - name: min_spend_scope
          in: query
          required: false
          description: >-
            Level at which `min_spend` is evaluated. Must be the request level
            or a coarser one (e.g. keywords rows thresholded by their campaign's
            total spend).
          schema:
            type: string
            enum:
              - campaigns
              - groups
              - keywords
        - name: limit
          in: query
          required: false
          description: >-
            Maximum rows to return. Default 100; range 1–500, or 1–5000 when
            `export=true`.
          schema:
            type: integer
            minimum: 1
            maximum: 5000
            default: 100
        - name: offset
          in: query
          required: false
          description: Pagination offset.
          schema:
            type: integer
            minimum: 0
            default: 0
        - name: export
          in: query
          required: false
          description: >-
            Lifts the `limit` ceiling to 5000 for one request. The response
            stays JSON. Accepts `true`/`false` or `1`/`0`.
          schema:
            type: boolean
            default: false
        - name: windows
          in: query
          required: false
          description: >-
            Optional cohort windows: a comma-separated subset of
            `d0,d3,d7,d14,d30,d60,d90,d180,d365,lifetime`. When present, every
            visible row (plus `total` and `unallocated`) carries a `windows`
            object keyed by the requested codes, and `meta.windows` describes
            the windows. Without this parameter no `windows` block is returned.
            `windows_mode` selects the reading (`growing` — every install of the
            period, counted to date — or `mature`). The closure rules below
            apply to the mature reading (`windows_mode=mature`); in the growing
            reading `closed_from`, `closed_through`, and `is_closed` are
            informational.

            In the mature reading a window of nominal length `n` days (`d0`
            means through the end of the install UTC day — not the first 24
            hours from the install moment — so its effective length is 1 day;
            the same holds in the growing reading) covers only install dates
            that have fully matured. A date `d` is closed when both hold:
            `today_utc - d >= length + maturation_buffer_days + 1` and
            `today_utc - d >=
            meta.windows.spend_snapshot.rewrite_days_effective`.

            `rewrite_days_effective` is the number of recent days whose spend
            Apple can still restate; these dates are not treated as closed,
            whatever the window length or `maturation_buffer_days`.

            Mature values therefore describe a closed subrange of `[from, to]`
            (`closed_from` to `closed_through`), not the whole requested window
            unless `is_closed` is `true`. `lifetime` never reports `is_closed:
            true`, because cumulative revenue keeps accruing.

            Duplicate codes are ignored, and the codes are returned in canonical
            order regardless of input order. An unknown code, such as `d31`,
            returns `400` naming the invalid token.
          schema:
            type: string
            example: d0,d7,d30,lifetime
        - name: maturation_buffer_days
          in: query
          required: false
          description: >-
            Extra full days a cohort date must age past its window length before
            it counts as closed in the mature reading. Used with `windows` and
            echoed in `meta.windows.maturation_buffer_days`.
            `meta.windows.spend_snapshot.rewrite_days_effective` applies
            independently of this value.
          schema:
            type: integer
            minimum: 0
            maximum: 30
            default: 4
        - name: windows_mode
          in: query
          required: false
          description: >-
            Which reading of the `windows` block to compute. Used only together
            with `windows`.


            `growing` — the to-date reading: the cohort is every install of the
            row in `[from, to]`, an event counts while it falls within the
            window length from its install and no later than today (`through`,
            the as-of UTC date), and the denominator is the row's Apple spend
            for the period (the same number as `apple.spend`). Values change day
            to day until the period matures; for a young period `d<n>` equals
            `lifetime`. Each window carries `mode: growing`, `through`, and
            `spend` (no `spend_closed`; `so_far` is `null`).


            `mature` — only install dates that have fully matured past the
            window length plus `maturation_buffer_days`, with the spend of those
            closed dates (`spend_closed`) and the provisional `so_far` reading;
            windows carry no `mode` key.


            When omitted, the server applies its default mode; send
            `windows_mode` explicitly when the reading matters.


            If you omit `windows_mode`, check `meta.windows.mode` for the
            reading served (in the growing reading, each window also carries
            `mode: growing`). If `meta.windows.mode` is absent, the response
            uses the mature reading. Any other value returns `400` naming
            `windows_mode`.
          schema:
            type: string
            enum:
              - growing
              - mature
        - name: filter[country][]
          in: query
          required: false
          description: >-
            Narrow the Qonversion cohort (and the Apple report where Apple
            supports the split) by storefront country. Array-valued — repeat the
            key for multiple values; the scalar form `filter[country]=US`
            returns `400`.
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
        - name: filter[campaign_name][]
          in: query
          required: false
          description: >-
            Narrow by campaign name. Array-valued — repeat the key for multiple
            values; the scalar form returns `400`.
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
        - name: filter[ad_set_name][]
          in: query
          required: false
          description: >-
            Narrow by ad group. On the groups and keywords levels it also
            narrows the Apple metrics; on the campaigns level it narrows the
            Qonversion cohort only. Array-valued — repeat the key for multiple
            values; the scalar form returns `400`.
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
        - name: filter[media_source_name][]
          in: query
          required: false
          description: >-
            Narrows the Qonversion cohort only; Apple spend is not split by
            media source. Array-valued — repeat the key for multiple values; the
            scalar form returns `400`.
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
        - name: filter[status]
          in: query
          required: false
          description: >-
            Keep rows whose Apple entity status matches. When Apple entity
            status is not available for the report, this filter matches no rows
            and `meta.status_data_unavailable` is `true`.
          schema:
            type: string
            enum:
              - active
              - paused
              - archived
        - name: filter[delivery]
          in: query
          required: false
          description: >-
            Keep rows whose delivery state matches. When Apple entity status is
            not available for the report, this filter matches no rows and
            `meta.status_data_unavailable` is `true`.
          schema:
            type: string
            enum:
              - delivering
              - not_delivering
        - name: filter_not[media_source_name][]
          in: query
          required: false
          description: >-
            Exclude these media sources from the Qonversion cohort — the
            complement of `filter[media_source_name][]`. Array-valued: repeat
            the key for multiple values.

            `filter_not[media_source_name][]` is the only supported exclusion;
            `filter_not` on the other filters of this report (`country`,
            `campaign_name`, `ad_set_name`, `status`, `delivery`) returns `400`.
          style: form
          explode: true
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: Apple Ads report for the requested level.
          headers:
            Cache-Control:
              schema:
                type: string
                example: no-cache
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V4AnalyticsAppleAdsReport'
              example:
                object: analytics_apple_ads_report
                url: /v4/analytics/apple-ads/report
                level: campaigns
                currency: USD
                revenue_type: gross
                status_data_available: true
                rows:
                  - campaign:
                      id: '1234567890'
                      name: Brand US
                      status:
                        state: ENABLED
                        serving: RUNNING
                        display: RUNNING
                        reasons: []
                      delivery: delivering
                    qonversion:
                      users: 1204
                      trials_started: 311
                      trials_converted: 96
                      direct_subscriptions: 12
                      in_apps: 4
                      unique_paying_users: 102
                      revenue_gross: 4210.55
                      revenue_net: 2947.39
                      refunds:
                        gross: 120
                        net: 84
                      arpu: 3.5
                      arppu: 41.28
                    apple:
                      impressions: 90210
                      taps: 4130
                      installs: 1188
                      total_installs: 1421
                      new_downloads: 1002
                      redownloads: 186
                      spend: 2105.4
                      ttr: 4.58
                      avg_cpa: 1.77
                      avg_cpt: 0.51
                      avg_cpm: 23.34
                    roas: 2
                    windows:
                      d7:
                        is_closed: true
                        closed_from: '2025-06-01'
                        closed_through: '2025-06-10'
                        spend_closed: 1402.1
                        cohort_size: 812
                        trials_started: 208
                        trials_converted: 61
                        payers: 66
                        revenue: 1893.2
                        roas: 1.35
                        cac: 21.24
                        cost_per_trial: 6.74
                      lifetime:
                        is_closed: false
                        closed_from: '2025-06-01'
                        closed_through: '2025-06-10'
                        spend_closed: 1680.3
                        cohort_size: 968
                        trials_started: 251
                        trials_converted: 78
                        payers: 83
                        revenue: 3120.44
                        roas: 1.86
                        cac: 20.24
                        cost_per_trial: 6.69
                total:
                  qonversion:
                    users: 1204
                    trials_started: 311
                    trials_converted: 96
                    direct_subscriptions: 12
                    in_apps: 4
                    unique_paying_users: 102
                    revenue_gross: 4210.55
                    revenue_net: 2947.39
                    refunds:
                      gross: 120
                      net: 84
                    arpu: 3.5
                    arppu: 41.28
                  apple:
                    impressions: 90210
                    taps: 4130
                    installs: 1188
                    total_installs: 1421
                    new_downloads: 1002
                    redownloads: 186
                    spend: 2105.4
                    ttr: 4.58
                    avg_cpa: 1.77
                    avg_cpt: 0.51
                    avg_cpm: 23.34
                  roas: 2
                  windows:
                    d7:
                      is_closed: true
                      closed_from: '2025-06-01'
                      closed_through: '2025-06-10'
                      spend_closed: 1402.1
                      cohort_size: 812
                      trials_started: 208
                      trials_converted: 61
                      payers: 66
                      revenue: 1893.2
                      roas: 1.35
                      cac: 21.24
                      cost_per_trial: 6.74
                    lifetime:
                      is_closed: false
                      closed_from: '2025-06-01'
                      closed_through: '2025-06-10'
                      spend_closed: 1680.3
                      cohort_size: 968
                      trials_started: 251
                      trials_converted: 78
                      payers: 83
                      revenue: 3120.44
                      roas: 1.86
                      cac: 20.24
                      cost_per_trial: 6.69
                unallocated: null
                pagination:
                  limit: 100
                  offset: 0
                  total_rows: 1
                  total_rows_unfiltered: 1
                  rows_without_spend_hidden: 0
                partial_sources: []
                meta:
                  updated_at:
                    subscriptions: '2025-06-22T11:00:00Z'
                    spend: '2025-06-22T13:46:40Z'
                  is_partial_period: false
                  partial_scope:
                    campaigns_total: 1
                    campaigns_missing: 0
                  windows:
                    mode: mature
                    maturation_buffer_days: 4
                    as_of_utc_date: '2025-06-22'
                    windows:
                      d7:
                        days: 7
                        closed_through: '2025-06-10'
                      lifetime:
                        days: null
                        closed_through: '2025-06-10'
                    unallocated_residual_negative: false
                    spend_snapshot:
                      available: true
                      error: false
                      first_date: '2025-01-04'
                      coverage_from: '2025-06-01'
                      coverage_to: '2025-06-21'
                      rewrite_days_effective: 3
                      note: null
                  semantics:
                    timezone: UTC
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V4Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V4Error'
        '403':
          description: Insufficient permissions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V4Error'
        '404':
          description: Not found. Also returned to accounts without Apple Ads enabled.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V4Error'
        '429':
          description: >-
            Rate limited. The response includes `Retry-After`; wait that long
            before retrying.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
                example: 60
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V4Error'
        '500':
          description: Internal error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V4Error'
        '502':
          description: Bad gateway
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V4Error'
        '504':
          description: Gateway timeout
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/V4Error'
      security:
        - secretAuth: []
components:
  schemas:
    V4AnalyticsAppleAdsReport:
      type: object
      required:
        - object
        - url
        - level
        - currency
        - revenue_type
        - rows
        - pagination
        - partial_sources
        - meta
      properties:
        object:
          type: string
          enum:
            - analytics_apple_ads_report
        url:
          type: string
        level:
          type: string
          enum:
            - campaigns
            - groups
            - keywords
        currency:
          type: string
          description: >-
            Currency of the monetary values — the `currency` request parameter
            (default `USD`). If no exchange rate is available for the period,
            values are in USD: `currency` is `USD` and
            `meta.rate_unavailable_for` holds the requested code.
        revenue_type:
          type: string
          enum:
            - gross
            - net
          description: >-
            Revenue basis of the derived metrics (`roas`, `arpu`, `arppu`,
            `windows.*.revenue`, `windows.*.roas`) — the echo of the
            `revenue_type` request parameter, default `gross`.
        status_data_available:
          type: boolean
          description: >-
            `false` when Apple entity status is not available for this report;
            `filter[status]` and `filter[delivery]` then match no rows.
        rows:
          type: array
          items:
            $ref: '#/components/schemas/V4AnalyticsAppleAdsReportRow'
        total:
          anyOf:
            - $ref: '#/components/schemas/V4AnalyticsAppleAdsReportRow'
            - type: object
              nullable: true
              enum:
                - null
          description: >-
            Whole-report totals row (unaffected by `q`, `min_spend`, status
            filters, and pagination). Carries the `qonversion` and `apple`
            blocks and the derived `roas`, `cost_per_subscription`, and
            `cost_per_trial` (plus `windows` when requested), with no campaign,
            ad group, or keyword block. The derived values are computed from the
            whole-report numerator and denominator, not summed from the rows on
            the page.
        unallocated:
          anyOf:
            - $ref: '#/components/schemas/V4AnalyticsAppleAdsReportRow'
            - type: object
              nullable: true
              enum:
                - null
          description: >-
            Spend and metrics Apple reports for the period that no row accounts
            for (for example, Search Match discovery spend without keywords).
            Carries the `qonversion` and `apple` blocks plus the derived ratios
            (and `windows` when requested); `qonversion` is always `null` here,
            and so is every cohort-based ratio (`roas`, `cost_per_subscription`,
            `cost_per_trial`).
        pagination:
          type: object
          properties:
            limit:
              type: integer
            offset:
              type: integer
            total_rows:
              type: integer
              description: Row count after report-level filters, before pagination.
            total_rows_unfiltered:
              type: integer
            rows_without_spend_hidden:
              type: integer
              description: >-
                Rows hidden by `min_spend` because they have no Apple spend data
                (not because they are under the threshold).
        partial_sources:
          type: array
          items:
            type: string
            enum:
              - apple_report
              - apple_status
          description: >-
            Apple data sources not included in this response (`apple_report` —
            Apple report metrics, `apple_status` — Apple entity status); empty
            when complete. Rows without Apple data have `apple: null`.
            Qonversion metrics are always complete.
        meta:
          type: object
          description: >-
            Response metadata — data timestamps (`updated_at`),
            `is_partial_period`, `currency_conversion`, `rate_unavailable_for`,
            `status_data_unavailable`, `partial_scope`, the request echo
            (`request`), the window details (`windows`, when requested), and the
            `semantics` dictionary that defines every metric (population,
            revenue bases, trial event counting, roas, filters, status and
            delivery, timezone).
          properties:
            updated_at:
              type: object
              description: Data timestamps, ISO 8601 UTC.
              properties:
                subscriptions:
                  type: string
                  format: date-time
                  nullable: true
                  description: >-
                    Time of the Qonversion subscription data behind the cohort
                    metrics.
                spend:
                  type: string
                  format: date-time
                  nullable: true
                  description: Time of the Apple spend data.
            is_partial_period:
              type: boolean
              description: The selected period includes a UTC day that has not ended.
            status_data_unavailable:
              type: boolean
              description: >-
                `true` when `filter[status]` or `filter[delivery]` was requested
                and Apple entity status is not available for this report; these
                filters then match no rows.
            partial_scope:
              type: object
              properties:
                campaigns_total:
                  type: integer
                  minimum: 0
                  description: Campaigns in the report.
                campaigns_missing:
                  type: integer
                  minimum: 0
                  description: >-
                    Campaigns without Apple data in this response; `0` when
                    complete.
              description: Counts campaigns without Apple data.
            request:
              type: object
              description: The request this response answers, after validation.
              properties:
                filters_applied:
                  type: object
                  additionalProperties: true
                  description: >-
                    The filters applied to this response, keyed by filter code
                    (`{}` when none). Check it to confirm that a filter took
                    effect.
            semantics:
              type: object
              additionalProperties: true
              description: >-
                Metric interpretation and source metadata, including textual
                definitions and structured event sets.
            currency_conversion:
              type: object
              nullable: true
              description: >-
                How the monetary values were converted from USD. `null` when the
                values are in USD — either `currency` is `USD` (the default) or
                no exchange rate is available for the period, in which case
                `rate_unavailable_for` holds the requested code.
              properties:
                rate:
                  type: number
                  description: >-
                    USD → target multiplier applied to every monetary value,
                    spend included.
                rate_date:
                  type: string
                  format: date
                  description: >-
                    UTC date the rate was taken from — the midpoint of `[from,
                    to]`, or the latest rate before it.
                method:
                  type: string
                  enum:
                    - single_midpoint_rate
                  description: One rate for the whole period, not per-day conversion.
            rate_unavailable_for:
              type: string
              nullable: true
              description: >-
                The requested currency code when no exchange rate is available
                for the period and the values are in USD; otherwise `null`. The
                top-level `currency` states the currency of the values.
            windows:
              type: object
              description: >-
                Present only when the request carried `windows` — the window
                details the per-row `windows` objects were computed with.
              properties:
                mode:
                  type: string
                  enum:
                    - growing
                    - mature
                  description: >-
                    The reading served — the `windows_mode` value when sent, the
                    server's default mode when omitted. If `meta.windows.mode`
                    is absent, the response uses the mature reading.
                maturation_buffer_days:
                  type: integer
                  description: >-
                    The `maturation_buffer_days` actually applied (echo of the
                    request parameter or its default of 4).
                as_of_utc_date:
                  type: string
                  format: date
                  description: >-
                    The UTC date against which closed dates were determined; the
                    same request returns the same window boundaries within this
                    day.
                windows:
                  type: object
                  description: Per requested code, the details of that window.
                  additionalProperties:
                    type: object
                    properties:
                      days:
                        type: integer
                        nullable: true
                        description: >-
                          Nominal day offset of the code (`null` for
                          `lifetime`). The effective length of `d0` is 1 day —
                          through the end of the install UTC day, not the first
                          24 hours from the install moment — while `days` is
                          `0`.
                      closed_through:
                        type: string
                        format: date
                        nullable: true
                        description: >-
                          Last closed install date for this window across the
                          whole report.
                unallocated_residual_negative:
                  type: boolean
                  description: >-
                    `true` when the `unallocated` row's `spend_closed` is not
                    reported (`null`) for this response.
                spend_snapshot:
                  type: object
                  description: Apple spend data coverage behind the windows.
                  properties:
                    available:
                      type: boolean
                      description: >-
                        `true` when spend data exists for the requested dates.
                        When `false`, every `spend_closed` (and therefore the
                        mature reading's `roas`, `cac`, and `cost_per_trial`) is
                        `null`; the growing reading uses `spend` and is not
                        affected.
                    error:
                      type: boolean
                      description: >-
                        `true` when spend data is unavailable for this request
                        (distinct from `available: false`); the mature reading's
                        window values are then `null`. Request the report again
                        later.
                    first_date:
                      type: string
                      format: date
                      nullable: true
                      description: >-
                        Earliest date with spend data for the project; windows
                        do not reach back past it.
                    coverage_from:
                      type: string
                      format: date
                      nullable: true
                      description: >-
                        First date with spend data within the requested range.
                        `closed_from` is never earlier than this date, and a
                        window that starts later than `from` does not report
                        `is_closed: true`.
                    coverage_to:
                      type: string
                      format: date
                      nullable: true
                      description: Last date with spend data within the requested range.
                    note:
                      type: string
                      nullable: true
                      description: >-
                        Human-readable explanation when `available` and `error`
                        are both `false`; otherwise `null`.
                    rewrite_days_effective:
                      type: integer
                      description: >-
                        The number of recent days whose spend Apple can still
                        restate; these dates are not treated as closed, whatever
                        `maturation_buffer_days` is.
    V4Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - code
            - message
          properties:
            type:
              type: string
              enum:
                - request
                - resource
                - logical
                - internal
            code:
              type: string
              description: |
                Machine-readable snake_case error code. Examples include
                `invalid_data`, `invalid_request`, `invalid_product_id`,
                `not_found`, `already_exists`, `offering_already_exists`,
                `product_not_in_project`, `cannot_set_main_directly`,
                `cannot_demote_main`, `cannot_patch_experiment_variant`,
                `cannot_delete_experiment_variant`, and
                `cannot_setmain_experiment_variant`. Resource-specific codes
                are documented on the corresponding reference page.
            message:
              type: string
              description: Human-readable description. May change; do not parse.
            details:
              type: array
              nullable: true
              description: Per-field validation errors, present on 400 validation failures.
              items:
                type: object
                properties:
                  field:
                    type: string
                  message:
                    type: string
    V4AnalyticsAppleAdsReportRow:
      type: object
      description: >-
        One report row. `campaign` is always present; `ad_group` appears on the
        groups and keywords levels, `keyword` (with `match_type`) on the
        keywords level only.
      properties:
        campaign:
          allOf:
            - $ref: '#/components/schemas/V4AnalyticsAppleAdsEntityRef'
            - type: object
              properties:
                daily_budget:
                  allOf:
                    - $ref: '#/components/schemas/V4AnalyticsAppleAdsMoneyInstruction'
                  description: >-
                    The campaign's daily budget. Present on the campaigns level
                    only; absent on the other levels (absent and `null` mean
                    different things here).
        ad_group:
          allOf:
            - $ref: '#/components/schemas/V4AnalyticsAppleAdsEntityRef'
            - type: object
              properties:
                bid:
                  allOf:
                    - $ref: '#/components/schemas/V4AnalyticsAppleAdsMoneyInstruction'
                  description: >-
                    The ad group's default bid. Present on the groups level
                    only; on the keywords level the `ad_group` block carries
                    neither status nor bid.
        keyword:
          allOf:
            - $ref: '#/components/schemas/V4AnalyticsAppleAdsEntityRef'
            - type: object
              properties:
                match_type:
                  type: string
                  nullable: true
                  description: Keyword match type as Apple reports it (e.g. EXACT/BROAD).
                bid:
                  allOf:
                    - $ref: '#/components/schemas/V4AnalyticsAppleAdsMoneyInstruction'
                  description: The keyword's own bid (keywords level only).
        qonversion:
          $ref: '#/components/schemas/V4AnalyticsAppleAdsQonversionBlock'
        apple:
          $ref: '#/components/schemas/V4AnalyticsAppleAdsAppleBlock'
        roas:
          type: number
          nullable: true
          description: >-
            Revenue (selected basis) / spend — a ratio, not a percentage, and
            not a closed ratio.
        cost_per_subscription:
          type: number
          nullable: true
          description: >-
            Period spend / `qonversion.unique_subscription_starters`, to date —
            the cost of one person who started a trial or a direct paid
            subscription. Not a closed metric: the denominator keeps growing
            after the period, so the value declines as the cohort matures (the
            closed counterpart is `windows.<code>.cac`, which divides closed
            spend by paying users). `null` — never `0` — without spend or
            starters. Always `null` on the `unallocated` row, which has no
            cohort.
        cost_per_trial:
          type: number
          nullable: true
          description: >-
            Period spend / `qonversion.trials_started`, to date. The denominator
            counts trial-start events, not unique users — unlike
            `cost_per_subscription`, which divides by unique people. Not the
            closed `windows.<code>.cost_per_trial`, which divides closed spend
            by the trials of those same closed dates. Same `null` rules as
            `cost_per_subscription`.
        windows:
          type: object
          description: >-
            Present only when the request carried `windows`. Keyed by the
            requested window codes (`d0`, `d3`, …, `d365`, `lifetime`), each
            value a `V4AnalyticsAppleAdsWindow` in the reading selected by
            `windows_mode` (one reading per response). Rows without cohort data
            still carry the keys, with every metric `null`.
          additionalProperties:
            $ref: '#/components/schemas/V4AnalyticsAppleAdsWindow'
    V4AnalyticsAppleAdsEntityRef:
      type: object
      description: Level entity reference — stable id plus the (mutable) display name.
      properties:
        id:
          type: string
        name:
          type: string
          nullable: true
        status:
          $ref: '#/components/schemas/V4AnalyticsAppleAdsEntityStatus'
        delivery:
          type: string
          nullable: true
          description: >-
            Delivery state of the row's entity: `delivering`, `not_delivering`,
            `paused`, or `unknown`.
    V4AnalyticsAppleAdsMoneyInstruction:
      type: object
      nullable: true
      required:
        - amount
        - currency
      description: >-
        A bid or daily budget set in Apple Ads (a keyword or ad group bid, a
        campaign daily budget) — a setting, not a measurement, so it follows
        different rules from the other monetary fields in this response.

        (1) It is in the advertising account's own currency and is not converted
        into the report `currency`; read `currency` from this object. (2)
        `amount` is a decimal string, returned exactly as Apple states it. (3)
        Reflects Apple's reporting metadata; not a confirmation of a recent
        change.

        `null`: not reported. It never means a bid or budget of zero.
      properties:
        amount:
          type: string
          description: Decimal string in `currency`, e.g. "2.50".
        currency:
          type: string
          description: ISO 4217 code of the advertising account, not of the report.
    V4AnalyticsAppleAdsQonversionBlock:
      type: object
      nullable: true
      description: Qonversion cohort outcomes for the row's entity.
      properties:
        users:
          type: integer
          description: Attributed installs in the cohort window.
        trials_started:
          type: integer
          description: Trial-start events (not unique users).
        trials_converted:
          type: integer
          description: Trial-conversion events.
        direct_subscriptions:
          type: integer
          description: Paid subscriptions started without a trial.
        in_apps:
          type: integer
          description: One-time in-app purchases.
        unique_paying_users:
          type: integer
        unique_paying_users_by_duration:
          type: object
          description: >-
            The paying users of this row split by subscription period. Not
            additive to `unique_paying_users`: a client who paid on two
            different periods is counted once in each bucket, so the buckets can
            sum to more than the total. Sortable with the `paying_<bucket>` sort
            keys.
          properties:
            weekly:
              type: integer
            monthly:
              type: integer
            annual:
              type: integer
            other:
              type: integer
        unique_subscription_starters:
          type: integer
          description: >-
            Denominator of `cost_per_subscription`: distinct cohort users who
            started a free trial or a direct paid subscription, counted once
            each. This is not `trials_started + direct_subscriptions`, which
            count events and would count a user with both, or with a repeat
            trial, twice. A trial converting to paid does not count the user
            again; one-time purchases are excluded.
        revenue_gross:
          type: number
          description: >-
            Cohort revenue to date, sales basis (after refunds, before store
            commission).
        revenue_net:
          type: number
          description: Cohort revenue to date, proceeds basis.
        refunds:
          type: object
          properties:
            gross:
              type: number
            net:
              type: number
        arpu:
          type: number
          description: Revenue (selected basis) per cohort user.
        arppu:
          type: number
          description: Revenue (selected basis) per unique paying user.
    V4AnalyticsAppleAdsAppleBlock:
      type: object
      nullable: true
      description: >-
        Apple Ads report metrics for the row's entity. `null` for rows without
        Apple data — not zero spend (see `partial_sources` and
        `meta.partial_scope`).
      properties:
        impressions:
          type: integer
        taps:
          type: integer
        installs:
          type: integer
          description: Tap-through installs (Apple attribution).
        total_installs:
          type: integer
          nullable: true
          description: Tap-through plus view-through installs, when Apple reports them.
        new_downloads:
          type: integer
        redownloads:
          type: integer
        spend:
          type: number
          description: >-
            Spend in the report's top-level `currency`, converted at the same
            single midpoint rate as revenue, so `roas` stays dimensionless.
        ttr:
          type: number
          nullable: true
          description: Tap-through rate, percent (taps / impressions * 100).
        avg_cpa:
          type: number
          nullable: true
          description: >-
            Average cost per tap-through install (spend / installs), as Apple
            reports it. Not CAC — the cost of acquiring a paying user is
            `windows.<code>.cac`.
        avg_cpt:
          type: number
          nullable: true
          description: Average cost per tap (spend / taps).
        avg_cpm:
          type: number
          nullable: true
          description: Average cost per thousand impressions.
    V4AnalyticsAppleAdsWindow:
      type: object
      description: >-
        One cohort window for one row, in one of two readings selected by
        `windows_mode`. The reading-specific keys are optional: the mature
        reading (`windows_mode=mature`) carries `spend_closed` and never `mode`,
        `through`, or `spend`; the growing reading carries `mode: growing`,
        `through`, and `spend` and never `spend_closed`. Every other key is
        common to both.


        Mature reading. Every value except `so_far` covers the row's closed
        install dates only — the interval `[closed_from, closed_through]`, which
        is a subrange of the requested `[from, to]` whenever the end of the
        range has not matured yet. The derived ratios are consistent with each
        other: `roas = revenue / spend_closed`, `cac = spend_closed / payers`,
        `cost_per_trial = spend_closed / trials_started`; all three are `null`
        whenever `spend_closed` is `null` or not positive. A partially closed
        row carries both readings: the closed metrics over `[closed_from,
        closed_through]` and `so_far` over the to-date interval that starts with
        those closed dates — quote the closed metrics as the more settled
        reading. `so_far` is `null` once the window fully closes (`is_closed:
        true`) and on `lifetime`.


        Growing reading (`windows_mode=growing`): what the row's installs have
        earned to date. The cohort is every install of the row in `[from, to]`;
        an event counts while it falls within the window length from its install
        (`d0` = through the end of the install UTC day) and no later than the
        end of `through`; `lifetime` counts every event through `through`. The
        denominator is the row's Apple spend for the whole period, identical to
        `apple.spend`, so numerator and denominator cover the same installs. The
        ratios are `roas = revenue / spend`, `cac = spend / payers`,
        `cost_per_trial = spend / trials_started`; all three are `null` when
        `spend` is `null` or not positive, `cac` also when `payers` is 0, and
        `cost_per_trial` also when `trials_started` is 0. Values are not final:
        they change day to day until the period matures, and for a young period
        `d<n>` equals `lifetime`. Compare rows of equal age only; for
        comparisons over matured install dates, request `windows_mode=mature`.
        Later refunds or revenue corrections can still change revenue. There is
        no `spend_closed` key in this reading.
      properties:
        mode:
          type: string
          enum:
            - growing
          description: >-
            Growing reading only — always `growing`. Absent in the mature
            reading.
        through:
          type: string
          format: date
          description: >-
            Growing reading only — the as-of UTC date (`YYYY-MM-DD`) events are
            counted through; equals `meta.windows.as_of_utc_date`.
        spend:
          type: number
          nullable: true
          description: >-
            Growing reading only — the row's Apple spend for the whole period,
            the same value as the row's `apple.spend` (`null` where
            `apple.spend` is `null`). In a non-USD report, the rows plus
            `unallocated` can differ from `total` by a rounding cent, as with
            `apple.spend`. The mature reading uses `spend_closed` instead.
        is_closed:
          type: boolean
          description: >-
            `true` only when every install date in the requested range has
            matured past this window and has spend data. Later refunds or
            revenue corrections can still change revenue. `lifetime` is never
            `true`. In the growing reading it is informational (the mature
            verdict).
        closed_from:
          type: string
          format: date
          nullable: true
          description: >-
            First install date (UTC, `YYYY-MM-DD`) included — the later of
            `from` and `meta.windows.spend_snapshot.coverage_from`. `null` when
            no date is closed yet. Informational in the growing reading; it does
            not bound the growing values.
        closed_through:
          type: string
          format: date
          nullable: true
          description: >-
            Last install date (UTC) included. `null` when no date is closed yet;
            every closed metric below is then `null` too, while `so_far` can
            still carry values. Informational in the growing reading; it does
            not bound the growing values.
        spend_closed:
          type: number
          nullable: true
          description: >-
            Apple spend of the closed dates. Additive: the rows' `spend_closed`
            plus `unallocated` equals the `total` row's.
        cohort_size:
          type: integer
          nullable: true
          description: >-
            Users acquired on the closed dates (growing — every install of the
            row in `[from, to]`).
        trials_started:
          type: integer
          nullable: true
          description: >-
            Trial starts within the window length from install. Counts events,
            not unique users. Growing — counted to date, through `through`.
        trials_converted:
          type: integer
          nullable: true
          description: >-
            Trial conversions within the window length from install. Counts
            events. Growing — counted to date, through `through`.
        payers:
          type: integer
          nullable: true
          description: >-
            Unique paying users within the window. Mature — from the closed
            cohort. Growing — from the whole cohort, counted to date (through
            `through`), so it can still grow.
        revenue:
          type: number
          nullable: true
          description: >-
            Revenue on the report's `revenue_type` basis, bounded by the window
            length from each install (unlike the row-level
            `qonversion.revenue_*`, which is cumulative to date). Growing — the
            to-date amount, also bounded by the end of `through`; it keeps
            moving until the period matures.
        roas:
          type: number
          nullable: true
          description: >-
            Mature — `revenue / spend_closed`, a closed ratio: unlike the
            row-level `roas`, both sides cover the same closed dates and the
            same elapsed window. Growing — `revenue / spend`, where `spend` is
            the row's Apple spend for the period (not `spend_closed`); a to-date
            value of a cohort that is still earning, not a closed ratio, and it
            changes day to day until the period matures.
        cac:
          type: number
          nullable: true
          description: >-
            CAC, the cost of acquiring one paying user. Mature — `spend_closed /
            payers`, closed. Growing — `spend / payers` with the row's Apple
            spend for the period as `spend` (not `spend_closed`); a to-date
            value that falls as the cohort keeps converting, not a closed ratio.
            This is the only CAC in this response; `apple.avg_cpa` is a
            different metric (Apple's cost per tap-through install).
        cost_per_trial:
          type: number
          nullable: true
          description: >-
            Mature — `spend_closed / trials_started`, closed. Growing — `spend /
            trials_started` with the row's Apple spend for the period as `spend`
            (not `spend_closed`); a to-date value, not a closed ratio.
        so_far:
          anyOf:
            - $ref: '#/components/schemas/V4AnalyticsAppleAdsWindowSoFar'
            - type: object
              nullable: true
              enum:
                - null
          description: >-
            The provisional reading of a window that is not fully closed: the
            window's outcomes over every install date with spend data so far,
            with the same per-install window bound and the spend of those same
            dates in the denominator. The covered interval runs from the later
            of the UTC date of the request's `from` and
            `meta.windows.spend_snapshot.coverage_from` through
            `so_far.through`. `null` when the window is fully closed
            (`is_closed: true`), on `lifetime` (its to-date value is the row's
            own), in the growing reading (its values already are the to-date
            reading), and when no provisional reading is available for the row.
            Treat an absent `so_far` like `null`. A refund counts at the time of
            the purchase it cancels, not at its own date, so a purchase and its
            refund are included or excluded together; a purchase after the end
            of the `so_far.through` UTC day is excluded together with its
            refund.
    V4AnalyticsAppleAdsEntityStatus:
      type: object
      nullable: true
      description: >-
        Apple entity status; `null` when Apple status is not available for the
        entity (`delivery` is then `unknown`).
      properties:
        state:
          type: string
          nullable: true
          description: User-set state (ENABLED/PAUSED; keywords ACTIVE/PAUSED).
        serving:
          type: string
          nullable: true
          description: >-
            Apple serving status (e.g. RUNNING, NOT_RUNNING). Keywords carry no
            serving status of their own.
        display:
          type: string
          nullable: true
          description: Apple display status; DELETED maps to the `archived` filter.
        reasons:
          type: array
          items:
            type: string
          description: Serving-state reasons, primary cause first.
    V4AnalyticsAppleAdsWindowSoFar:
      type: object
      required:
        - through
        - spend
        - cohort_size
        - payers
        - revenue
        - roas
        - cac
      description: >-
        Provisional values for install dates that have not yet completed the
        window plus the maturation buffer; they change until those dates close.
        The ratios use the same dates on both sides: `roas = revenue / spend`,
        `cac = spend / payers`. A purchase counts at its own time and a refund
        at the time of the purchase it cancels, so a purchase and its refund are
        included or excluded together (a purchase inside the window whose refund
        came later is netted); a purchase after the end of the `through` UTC day
        is excluded together with its refund.
      properties:
        through:
          type: string
          format: date
          description: >-
            Last install date (UTC, `YYYY-MM-DD`) the reading covers — the row's
            last install date, no later than
            `meta.windows.spend_snapshot.coverage_to`.
        spend:
          type: number
          description: Apple spend of the covered install dates.
        cohort_size:
          type: integer
          description: Users acquired on the covered install dates.
        payers:
          type: integer
          description: >-
            Unique paying users so far, same per-install calendar bound as the
            closed window.
        revenue:
          type: number
          description: >-
            Revenue on the report's `revenue_type` basis, bounded by the window
            length from each install and by the end of the `through` UTC day,
            with refunds netted at the time of the purchase they cancel.
        roas:
          type: number
          description: '`revenue / spend`. `0` means no revenue yet.'
        cac:
          type: number
          nullable: true
          description: '`spend / payers`; `null` until the cohort has a paying user.'
  securitySchemes:
    secretAuth:
      type: http
      scheme: bearer
      bearerFormat: sk_…
      description: >-
        Bearer authentication using the project **Secret Key** (prefixed with
        `sk_`), used exactly as shown in the dashboard. Endpoints that support
        sandbox data take an explicit `environment` field or parameter. All v4
        public endpoints require the Secret Key — see
        [Authentication](/reference/v4/authentication). Never expose the Secret
        Key in client-side code.

````