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

# Get reporting

> Get reporting metrics across all advertisers and campaigns. The response is hierarchical for view=summary, flat leaf-by-day rows for view=timeseries, or a signed CSV download descriptor when download=true.



## OpenAPI

````yaml /v2/buyer-api-v2.yaml get /reporting/metrics
openapi: 3.0.0
info:
  title: Scope3 Buyer API
  version: 2.0.0
  description: |-
    REST API for advertisers to manage advertisers, campaigns, and reporting.

    ## Authentication

    All endpoints require a Bearer token in the Authorization header:
    ```
    Authorization: Bearer your-api-key
    ```

    ## Base URL

    `https://api.apostra.com/api/v2/buyer`

    ## For AI Agents

    AI agents can use the MCP endpoint at `/mcp/v2/buyer` with three tools:
    - `initialize`: Start an MCP session
    - `api_call`: Make REST API calls
    - `ask_about_capability`: Learn about API features
servers:
  - url: https://api.apostra.com/api/v2/buyer
    description: Production server
security: []
tags:
  - name: Signup
    description: Request reviewed access to Interchange
  - name: Account
    description: Account management, service tokens, and preferences
  - name: Asks
    description: >-
      What you are waiting on Scope3 for — support, product, and supply asks in
      one list
  - name: Advertisers
    description: Manage advertisers
  - name: Product Discovery
    description: Discover and select products
  - name: Campaigns
    description: Manage advertising campaigns
  - name: Creatives
    description: Build, manage, and sync campaign creatives via AdCP Creative Protocol
  - name: Reporting
    description: Access performance metrics
  - name: Event Sources
    description: >-
      Manage event source configurations and log conversion/marketing events for
      attribution
  - name: Property Lists
    description: Validate property lists against AAO registry
  - name: Sales Agents
    description: View and connect sales agents
  - name: Measurement
    description: Measurement sources, records, context, and freshness
  - name: Syndication
    description: Syndicate resources to ADCP agents
  - name: Tasks
    description: Track async operation status
  - name: Buyer Billing
    description: >-
      Consolidated invoicing for buyers — invoices and pending invoice items
      issued by Scope3 across the buyer customer.
  - name: MCP
    description: Model Context Protocol endpoints for AI agents
paths:
  /reporting/metrics:
    get:
      tags:
        - Reporting
      summary: Get reporting
      description: >-
        Get reporting metrics across all advertisers and campaigns. The response
        is hierarchical for view=summary, flat leaf-by-day rows for
        view=timeseries, or a signed CSV download descriptor when download=true.
      operationId: getReportingMetrics
      parameters:
        - in: query
          name: advertiserId
          schema:
            description: Filter to campaigns on this advertiser
            type: string
          description: Filter to campaigns on this advertiser
        - in: query
          name: campaignId
          schema:
            description: >-
              Filter to a specific campaign. If advertiserId is also provided,
              the campaign must belong to that advertiser
            type: string
          description: >-
            Filter to a specific campaign. If advertiserId is also provided, the
            campaign must belong to that advertiser
        - in: query
          name: channelGroupId
          schema:
            description: >-
              Filter to media buys in one campaign channel group. May be
              combined with advertiserId or campaignId to assert the expected
              parent scope
            type: string
            minLength: 1
            maxLength: 128
          description: >-
            Filter to media buys in one campaign channel group. May be combined
            with advertiserId or campaignId to assert the expected parent scope
        - in: query
          name: mediaBuyId
          schema:
            description: >-
              Filter to a specific media buy owned by the authenticated buyer.
              May be combined with advertiserId or campaignId to assert the
              expected parent scope
            type: string
          description: >-
            Filter to a specific media buy owned by the authenticated buyer. May
            be combined with advertiserId or campaignId to assert the expected
            parent scope
        - in: query
          name: startDate
          schema:
            description: Start date in ISO format (YYYY-MM-DD)
            example: '2025-01-01'
            type: string
            pattern: ^\d{4}-\d{2}-\d{2}$
          description: Start date in ISO format (YYYY-MM-DD)
        - in: query
          name: endDate
          schema:
            description: End date in ISO format (YYYY-MM-DD)
            example: '2025-01-31'
            type: string
            pattern: ^\d{4}-\d{2}-\d{2}$
          description: End date in ISO format (YYYY-MM-DD)
        - in: query
          name: days
          schema:
            default: 7
            description: >-
              Number of days to include (default: 7, max: 90). Use 0 for the
              full campaign timeframe.
            example: 7
            type: integer
            minimum: 0
            maximum: 90
          description: >-
            Number of days to include (default: 7, max: 90). Use 0 for the full
            campaign timeframe.
        - in: query
          name: view
          schema:
            default: summary
            description: >-
              Response format: "summary" for hierarchical
              advertiser/campaign/media-buy/package breakdown, "timeseries" for
              flat rows with one entry per (advertiser → campaign → media buy →
              package) × day
            type: string
            enum:
              - summary
              - timeseries
          description: >-
            Response format: "summary" for hierarchical
            advertiser/campaign/media-buy/package breakdown, "timeseries" for
            flat rows with one entry per (advertiser → campaign → media buy →
            package) × day
        - in: query
          name: displayCurrency
          schema:
            description: >-
              ISO-4217 currency for the consolidated (FX-converted)
              cross-advertiser rollup. Defaults to the buyer home currency when
              the advertisers share one; must be a platform-supported currency.
              Summary view only. The converted figures are display estimates,
              never billing inputs
            example: EUR
            type: string
            pattern: ^[A-Za-z]{3}$
          description: >-
            ISO-4217 currency for the consolidated (FX-converted)
            cross-advertiser rollup. Defaults to the buyer home currency when
            the advertisers share one; must be a platform-supported currency.
            Summary view only. The converted figures are display estimates,
            never billing inputs
        - in: query
          name: download
          schema:
            description: >-
              When true, generates a CSV file and returns a signed download URL
              instead of JSON data
            default: false
            type: boolean
          description: >-
            When true, generates a CSV file and returns a signed download URL
            instead of JSON data
        - in: query
          name: demo
          schema:
            description: >-
              When true, returns auto-generated demo data instead of querying
              real data sources
            default: false
            type: boolean
          description: >-
            When true, returns auto-generated demo data instead of querying real
            data sources
      responses:
        '200':
          description: Get reporting
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ReportingMetricsResponse'
                  - $ref: '#/components/schemas/ReportingMetricsTimeseriesResponse'
                  - $ref: '#/components/schemas/ReportingMetricsExportResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearerAuth: []
components:
  schemas:
    ReportingMetricsResponse:
      type: object
      properties:
        synthetic:
          description: >-
            Present only for synthetic demo data. The notice states that the
            data is unsuitable for commercial decisions.
          type: object
          properties:
            scenarioId:
              type: string
            notice:
              type: string
          required:
            - scenarioId
            - notice
          additionalProperties: false
        advertisers:
          type: array
          items:
            $ref: '#/components/schemas/AdvertiserReporting'
          description: Advertiser-level reporting data
        totals:
          description: >-
            Aggregated totals across all advertisers, exact and native. Money
            metrics are present only when every advertiser shares one currency
            (totalsCurrency); when currencies mix they are null — see the
            consolidated block for the converted rollup
          allOf:
            - $ref: '#/components/schemas/ReportingTotalsMetrics'
        totalsCurrency:
          nullable: true
          description: >-
            ISO-4217 currency the native totals are denominated in; null when
            the advertisers span multiple currencies (money metrics in totals
            are then null)
          type: string
        consolidated:
          description: >-
            FX-converted cross-advertiser rollup in the display currency
            (explicit displayCurrency, or the buyer home currency when
            resolvable). Omitted when no conversion applies (single-currency
            buyer viewing natively). Display estimate only — never a billing
            input
          nullable: true
          allOf:
            - $ref: '#/components/schemas/ConsolidatedReporting'
        periodStart:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: Start of the reporting period (YYYY-MM-DD)
        periodEnd:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: End of the reporting period (YYYY-MM-DD)
      required:
        - advertisers
        - totals
        - totalsCurrency
        - periodStart
        - periodEnd
      additionalProperties: false
      description: >-
        Hierarchical reporting response: advertiser → campaign → media buy →
        package
    ReportingMetricsTimeseriesResponse:
      type: object
      properties:
        synthetic:
          description: >-
            Present only for synthetic demo data. The notice states that the
            data is unsuitable for commercial decisions.
          type: object
          properties:
            scenarioId:
              type: string
            notice:
              type: string
          required:
            - scenarioId
            - notice
          additionalProperties: false
        timeseries:
          type: array
          items:
            $ref: '#/components/schemas/TimeseriesEntry'
          description: >-
            Flat rows: one entry per (advertiser → campaign → media buy →
            package) × day, sorted by date ascending
        totals:
          description: >-
            Aggregated totals across the entire period. Money metrics are null
            when the emitted rows span currencies
          allOf:
            - $ref: '#/components/schemas/ReportingTotalsMetrics'
        totalsCurrency:
          nullable: true
          description: >-
            ISO-4217 currency the returned-row totals are denominated in; null
            when there are no rows or emitted rows span multiple currencies
          type: string
        goalProgress:
          description: >-
            Goal progress over the whole period for every media buy and campaign
            in the rows, for buys with a goal commitment or campaigns with a
            goal.
          type: object
          properties:
            mediaBuys:
              type: array
              items:
                type: object
                properties:
                  mediaBuyId:
                    type: string
                  campaignId:
                    nullable: true
                    type: string
                  progress:
                    $ref: '#/components/schemas/GoalProgress'
                required:
                  - mediaBuyId
                  - campaignId
                  - progress
                additionalProperties: false
            campaigns:
              type: array
              items:
                type: object
                properties:
                  campaignId:
                    type: string
                  progress:
                    $ref: '#/components/schemas/GoalProgress'
                required:
                  - campaignId
                  - progress
                additionalProperties: false
          required:
            - mediaBuys
            - campaigns
          additionalProperties: false
        periodStart:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: Start of the reporting period (YYYY-MM-DD)
        periodEnd:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: End of the reporting period (YYYY-MM-DD)
      required:
        - timeseries
        - totals
        - totalsCurrency
        - periodStart
        - periodEnd
      additionalProperties: false
      description: >-
        Time-series reporting response: flat leaf × day rows (same hierarchy
        fields as the summary view, plus date)
    ReportingMetricsExportResponse:
      type: object
      properties:
        synthetic:
          description: >-
            Present only for a synthetic demo export. The notice states that the
            data is unsuitable for commercial decisions.
          type: object
          properties:
            scenarioId:
              type: string
            notice:
              type: string
          required:
            - scenarioId
            - notice
          additionalProperties: false
        downloadUrl:
          type: string
          format: uri
          description: Signed URL to download the CSV file (expires in 7 days)
        expiresAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
          description: ISO 8601 timestamp when the download URL expires
        fileName:
          type: string
          description: Name of the generated CSV file
        rowCount:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Number of data rows in the CSV (excluding header)
      required:
        - downloadUrl
        - expiresAt
        - fileName
        - rowCount
      additionalProperties: false
      description: Response containing a signed URL to download the exported CSV
    ErrorResponse:
      type: object
      properties:
        data:
          type: string
          nullable: true
          enum:
            - null
        error:
          $ref: '#/components/schemas/ApiError'
      required:
        - data
        - error
      additionalProperties: false
      description: Standard error response
    AdvertiserReporting:
      type: object
      properties:
        advertiserId:
          type: string
          description: Advertiser identifier
        advertiserName:
          type: string
          description: Advertiser name
        currency:
          type: string
          description: >-
            ISO-4217 currency used for money under this advertiser (the
            advertiser's locked primary currency); source delivery spend is
            normalized to it when an applicable FX rate is available
        metrics:
          $ref: '#/components/schemas/ReportingMetrics'
        campaigns:
          type: array
          items:
            $ref: '#/components/schemas/CampaignReporting'
          description: Campaign-level breakdown
      required:
        - advertiserId
        - advertiserName
        - currency
        - metrics
        - campaigns
      additionalProperties: false
      description: Advertiser-level reporting metrics with campaign breakdown
    ReportingTotalsMetrics:
      type: object
      properties:
        impressions:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total impressions
        spend:
          nullable: true
          description: >-
            Total spend (gross, fee-inclusive — the buyer denomination) in the
            currency named by totalsCurrency; null when the returned data spans
            currencies or has no denomination
          type: number
          minimum: 0
        clicks:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total clicks
        views:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: >-
            Content views as the seller counts them, per AdCP: a
            platform-defined video view (for example 30 seconds or the
            midpoint), an audio stream start, or the view event defined by the
            package's pricing model. This is the billable quantity for CPV
            pricing. It is not a count of viewable impressions and must not be
            used to calculate a viewability rate.
        completedViews:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: >-
            Video/audio completions (qualified by view_duration_seconds when set
            on the goal)
        conversions:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total conversions
        leads:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total leads
        videoCompletions:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total video completions
        conversionValue:
          nullable: true
          description: >-
            Total conversion value in the currency named by totalsCurrency; null
            when the returned data spans currencies or has no denomination
          type: number
          minimum: 0
        ecpm:
          nullable: true
          description: >-
            Effective CPM: (spend * 1000) / impressions, derived from spend in
            this surface's denomination (gross fee-inclusive on buyer surfaces);
            null when impressions is 0
          type: number
        cpc:
          nullable: true
          description: >-
            Cost per click: spend / clicks, derived from spend in this surface's
            denomination (gross fee-inclusive on buyer surfaces); null when
            clicks is 0
          type: number
        ctr:
          nullable: true
          description: 'Click-through rate: clicks / impressions'
          type: number
        completionRate:
          nullable: true
          description: >-
            Completion rate: completedViews / impressions (completions per paid
            impression; impressions is the paid unit for CPM video)
          type: number
        cpa:
          nullable: true
          description: >-
            Cost per acquisition: spend / conversions, derived from spend in
            this surface's denomination (gross fee-inclusive on buyer surfaces);
            null when conversions is 0
          type: number
        roas:
          nullable: true
          description: >-
            Return on ad spend: conversionValue / spend; null when spend is 0,
            or when there is no conversion signal at all (conversionValue and
            conversions are both 0). Reports a true 0 when conversions are real
            but attributed value is zero. conversionValue carries no platform
            fee while spend is gross fee-inclusive on buyer surfaces, so buyer
            ROAS reads lower than storefront ROAS for identical delivery — the
            same denomination difference that already separates buyer and
            storefront cpc/ecpm.
          type: number
      required:
        - impressions
        - spend
        - clicks
        - views
        - completedViews
        - conversions
        - leads
        - videoCompletions
        - conversionValue
        - ecpm
        - cpc
        - ctr
        - completionRate
        - cpa
        - roas
      additionalProperties: false
      description: >-
        Reporting totals; money metrics are null when returned denominations mix
        or no denomination is available
    ConsolidatedReporting:
      type: object
      properties:
        totals:
          description: >-
            Cross-advertiser totals in the display currency: counts summed
            natively, money converted per advertiser then summed; money-derived
            metrics are null when any advertiser could not be converted
          allOf:
            - $ref: '#/components/schemas/ReportingTotalsMetrics'
        byAdvertiser:
          type: array
          items:
            type: object
            properties:
              advertiserId:
                type: string
              currency:
                type: string
                description: The advertiser native currency this row converted from
              spend:
                nullable: true
                description: >-
                  This advertiser spend converted to the display currency; null
                  when its pair had no rate
                type: number
            required:
              - advertiserId
              - currency
              - spend
            additionalProperties: false
          description: >-
            Per-advertiser converted spend so the consolidated total is
            auditable row by row
        conversionInfo:
          $ref: '#/components/schemas/ReportingConversionInfo'
      required:
        - totals
        - byAdvertiser
        - conversionInfo
      additionalProperties: false
      description: >-
        FX-converted cross-advertiser rollup (display estimate only — never
        billing)
    TimeseriesEntry:
      type: object
      properties:
        date:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: Reporting date (YYYY-MM-DD)
          example: '2025-01-15'
        advertiserId:
          type: string
          description: Advertiser identifier
        advertiserName:
          type: string
          description: Advertiser name
        currency:
          type: string
          description: >-
            ISO-4217 currency that actually denominates the row's spend, eCPM,
            and CPC; normally the advertiser's locked primary currency, or the
            reported source currency when FX conversion is unavailable
        campaignId:
          type: string
          description: Campaign identifier
        campaignName:
          type: string
          description: Campaign name
        management:
          description: >-
            Management state of the row's campaign: "tracked" (mirrored
            read-only from a connected provider account) or "managed" (authored
            or adopted through the platform). Rows without a campaign are
            managed.
          allOf:
            - $ref: '#/components/schemas/CampaignManagement'
        mediaBuyId:
          type: string
          description: Media buy identifier
        mediaBuyName:
          type: string
          description: Media buy name
        channelGroupId:
          description: Campaign channel group identifier, or null when ungrouped.
          nullable: true
          type: string
        channelGroupName:
          description: Campaign channel group name, or null when ungrouped.
          nullable: true
          type: string
        mediaBuyStatus:
          type: string
          description: Media buy status
        packageId:
          type: string
          description: Package identifier. Empty string when the media buy has no packages.
        productId:
          type: string
          description: Product identifier for this package. Empty string when no package.
        productName:
          type: string
          description: >-
            Human-readable product name for this package. Empty string when no
            package.
        metrics:
          $ref: '#/components/schemas/ReportingMetrics'
      required:
        - date
        - advertiserId
        - advertiserName
        - currency
        - campaignId
        - campaignName
        - management
        - mediaBuyId
        - mediaBuyName
        - mediaBuyStatus
        - packageId
        - productId
        - productName
        - metrics
      additionalProperties: false
      description: >-
        One row of metrics for a single (advertiser → campaign → media buy →
        package) leaf on a single day
    GoalProgress:
      type: object
      properties:
        goal:
          nullable: true
          description: >-
            The buyer's goal being judged: the commitment's asked goal, else the
            campaign's primary goal. Null when only a fixed outcome price is on
            record.
          type: object
          properties:
            kind:
              type: string
              enum:
                - metric
                - event
            subject:
              type: string
              description: >-
                The metric name for a metric goal; the event type(s) joined with
                | for an event goal.
            eventTypes:
              type: array
              items:
                type: string
            target:
              nullable: true
              allOf:
                - $ref: '#/components/schemas/GoalProgressTarget'
          required:
            - kind
            - subject
            - eventTypes
            - target
          additionalProperties: false
        askedTarget:
          nullable: true
          description: The target the buyer asked for, when the goal carries one.
          allOf:
            - $ref: '#/components/schemas/GoalProgressTarget'
        answeredTarget:
          nullable: true
          description: >-
            The cost or return the seller's terms commit or aim at, from the
            media buy's goal commitment.
          allOf:
            - $ref: '#/components/schemas/GoalProgressTarget'
        commitment:
          nullable: true
          description: >-
            The commitment kind on the media buy, or the weakest across a
            campaign; null when no buy carries one.
          type: string
          enum:
            - guaranteed
            - best_effort
            - report_only
        commitmentSource:
          nullable: true
          description: >-
            Where a media buy commitment came from; null at campaign level,
            where buys may differ.
          type: string
          enum:
            - proposal
            - campaign
        actual:
          nullable: true
          description: >-
            The achieved cost per unit (per thousand for impressions), rate over
            the metric's own denominator, or volume for the goal's metric,
            computed from the same delivery this response reports. Null when the
            metric was not reported or has no observations.
          type: object
          properties:
            kind:
              type: string
              enum:
                - cost_per
                - threshold_rate
                - volume
            value:
              type: number
            unit:
              type: string
              enum:
                - impressions
                - clicks
                - views
                - completedViews
                - conversions
                - leads
                - viewableImpressions
            units:
              type: number
              minimum: 0
            denominatorUnits:
              nullable: true
              description: >-
                What a threshold_rate divided by: measurable impressions for a
                viewable rate, impressions for every other rate. Null for a cost
                or a volume.
              type: number
              minimum: 0
            perUnits:
              anyOf:
                - type: number
                  enum:
                    - 1
                - type: number
                  enum:
                    - 1000
              description: >-
                How many units a cost_per value prices: 1000 for impressions (a
                price per thousand, like CPM), 1 for every other unit.
            currency:
              nullable: true
              type: string
          required:
            - kind
            - value
            - unit
            - units
            - denominatorUnits
            - perUnits
            - currency
          additionalProperties: false
        verdict:
          nullable: true
          description: >-
            How delivery compares with the target. Null whenever the evidence
            does not support a verdict; see verdictWithheld.
          type: string
          enum:
            - on_track
            - behind
            - beat
        judgedAgainst:
          nullable: true
          description: >-
            Which target the verdict compares against: the buyer's asked target,
            or the seller's answered price when the buyer stated none.
          type: string
          enum:
            - asked
            - answered
        verdictWithheld:
          nullable: true
          description: >-
            Why there is no verdict. metric_unsupported covers metrics delivery
            does not carry (reach, attention), event goals other than lead-only
            ones and return-on-ad-spend targets, which need event-scoped counts
            this surface does not have. Too few observations means the metric is
            real but below the minimum count that makes a comparison meaningful.
          type: string
          enum:
            - no_goal
            - no_target
            - metric_unsupported
            - metric_not_reported
            - too_few_observations
        basis:
          nullable: true
          description: Who counted the number. Delivery on this surface is seller reported.
          type: object
          properties:
            kind:
              type: string
              enum:
                - seller_attested
          required:
            - kind
          additionalProperties: false
        freshness:
          type: object
          properties:
            dataThrough:
              nullable: true
              type: string
            reportingPeriodEnd:
              nullable: true
              type: string
            nextExpectedAt:
              nullable: true
              type: string
            notificationType:
              nullable: true
              type: string
            sequenceNumber:
              nullable: true
              type: number
            awaitingLaterReport:
              type: boolean
            missingMetrics:
              type: array
              items:
                type: string
          required:
            - dataThrough
            - reportingPeriodEnd
            - nextExpectedAt
            - notificationType
            - sequenceNumber
            - awaitingLaterReport
            - missingMetrics
          additionalProperties: false
        pace:
          nullable: true
          description: >-
            How the money is pacing against the flight, judged separately from
            the goal itself, so "$200 a day at 80% viewable" reads as two
            answers. Null when the surface does not know this scope's budget and
            flight.
          allOf:
            - $ref: '#/components/schemas/DeliveryPace'
      required:
        - goal
        - askedTarget
        - answeredTarget
        - commitment
        - commitmentSource
        - actual
        - verdict
        - judgedAgainst
        - verdictWithheld
        - basis
        - freshness
        - pace
      additionalProperties: false
      description: >-
        How delivery compares with the buyer's goal: the goal and targets, the
        seller's commitment, the achieved value, a verdict only when the
        evidence supports one, who counted the number, and how fresh it is.
    ApiError:
      type: object
      properties:
        code:
          type: string
          description: Machine-readable error code
        message:
          type: string
          description: Human-readable error message
        field:
          description: Field path associated with the error
          type: string
        details:
          description: Additional error context
          type: object
          additionalProperties: {}
      required:
        - code
        - message
      additionalProperties: false
      description: Structured error object
    ReportingMetrics:
      type: object
      properties:
        impressions:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total impressions
        spend:
          type: number
          minimum: 0
          description: >-
            Total spend, denominated in the advertiser's primary currency (every
            campaign and buy is stamped in that currency; USD only for USD
            advertisers). On BUYER surfaces spend is GROSS (fee-inclusive):
            seller-reported net delivered spend is grossed up at read time at
            each buy's own pinned terms (a buy without pinned terms reports net
            as stored). On STOREFRONT surfaces spend stays NET as the seller
            reported it.
        clicks:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total clicks
        views:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: >-
            Content views as the seller counts them, per AdCP: a
            platform-defined video view (for example 30 seconds or the
            midpoint), an audio stream start, or the view event defined by the
            package's pricing model. This is the billable quantity for CPV
            pricing. It is not a count of viewable impressions and must not be
            used to calculate a viewability rate.
        completedViews:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: >-
            Video/audio completions (qualified by view_duration_seconds when set
            on the goal)
        conversions:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total conversions
        leads:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total leads
        videoCompletions:
          type: integer
          minimum: 0
          maximum: 9007199254740991
          description: Total video completions
        conversionValue:
          type: number
          minimum: 0
          description: >-
            Total conversion value (advertiser-attributed revenue from
            conversions), denominated the same as spend. Unlike spend,
            conversion value is never grossed up on buyer surfaces — it is
            advertiser revenue, not marketplace spend, so it carries no platform
            fee.
        ecpm:
          nullable: true
          description: >-
            Effective CPM: (spend * 1000) / impressions, derived from spend in
            this surface's denomination (gross fee-inclusive on buyer surfaces);
            null when impressions is 0
          type: number
        cpc:
          nullable: true
          description: >-
            Cost per click: spend / clicks, derived from spend in this surface's
            denomination (gross fee-inclusive on buyer surfaces); null when
            clicks is 0
          type: number
        ctr:
          nullable: true
          description: 'Click-through rate: clicks / impressions'
          type: number
        completionRate:
          nullable: true
          description: >-
            Completion rate: completedViews / impressions (completions per paid
            impression; impressions is the paid unit for CPM video)
          type: number
        cpa:
          nullable: true
          description: >-
            Cost per acquisition: spend / conversions, derived from spend in
            this surface's denomination (gross fee-inclusive on buyer surfaces);
            null when conversions is 0
          type: number
        roas:
          nullable: true
          description: >-
            Return on ad spend: conversionValue / spend; null when spend is 0,
            or when there is no conversion signal at all (conversionValue and
            conversions are both 0). Reports a true 0 when conversions are real
            but attributed value is zero. conversionValue carries no platform
            fee while spend is gross fee-inclusive on buyer surfaces, so buyer
            ROAS reads lower than storefront ROAS for identical delivery — the
            same denomination difference that already separates buyer and
            storefront cpc/ecpm.
          type: number
      required:
        - impressions
        - spend
        - clicks
        - views
        - completedViews
        - conversions
        - leads
        - videoCompletions
        - conversionValue
        - ecpm
        - cpc
        - ctr
        - completionRate
        - cpa
        - roas
      additionalProperties: false
      description: Raw and calculated reporting metrics
    CampaignReporting:
      type: object
      properties:
        campaignId:
          type: string
          description: Campaign identifier
        campaignName:
          type: string
          description: Campaign name
        management:
          description: >-
            Management state of this campaign: "tracked" (a campaign the
            platform did not set up, mirrored read-only from a connected
            provider account) or "managed" (authored or adopted through the
            platform). Buyer reporting currently includes managed campaigns only
            — tracked mirror delivery is excluded from this surface — so
            aggregates never silently mix the two states.
          allOf:
            - $ref: '#/components/schemas/CampaignManagement'
        metrics:
          $ref: '#/components/schemas/ReportingMetrics'
        goalProgress:
          description: >-
            Delivery across the campaign's buys judged against its primary goal,
            with the weakest commitment across those buys. Absent when the
            campaign has no goal and no buy carries a commitment.
          nullable: true
          allOf:
            - $ref: '#/components/schemas/GoalProgress'
        mediaBuys:
          type: array
          items:
            $ref: '#/components/schemas/MediaBuyReporting'
          description: Media buy-level breakdown
      required:
        - campaignId
        - campaignName
        - management
        - metrics
        - mediaBuys
      additionalProperties: false
      description: Campaign-level reporting metrics with media buy breakdown
    ReportingConversionInfo:
      type: object
      properties:
        displayCurrency:
          type: string
          description: ISO-4217 currency the consolidated block is expressed in
        asOf:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
          description: >-
            UTC calendar day whose locked rate-of-the-day was applied (one rate
            across the whole window)
        rateSource:
          type: string
          enum:
            - fx_rate_snapshots
          description: Where the rates came from (the platform rate-of-day table)
        rateBasis:
          type: string
          enum:
            - as-of
          description: >-
            Conversion basis: 'as-of' applies one current rate-of-the-day to the
            whole window (an estimate; a booked-rate basis is a later phase)
        rates:
          type: array
          items:
            type: object
            properties:
              pair:
                type: string
                description: BASEQUOTE pair, e.g. USDZAR = ZAR per USD
              rate:
                type: number
                description: QUOTE units per 1 BASE
            required:
              - pair
              - rate
            additionalProperties: false
          description: Every rate applied in this conversion
        unconverted:
          type: array
          items:
            type: string
          description: >-
            Native currencies that could NOT be converted (no rate available);
            their spend is excluded from the consolidated money totals rather
            than guessed
        estimate:
          type: boolean
          enum:
            - true
          description: >-
            Always true: the consolidated figures are display estimates, never
            billing or settlement inputs
      required:
        - displayCurrency
        - asOf
        - rateSource
        - rateBasis
        - rates
        - unconverted
        - estimate
      additionalProperties: false
      description: How the consolidated (FX-converted) figures were produced
    CampaignManagement:
      type: string
      enum:
        - tracked
        - managed
      description: >-
        Whether the platform acts on this campaign. "tracked" = a campaign the
        platform did not set up, mirrored from a connected provider account: the
        shell is derived from the buys underneath, read-only, and updates
        automatically as the upstream campaign changes. "managed" = a campaign
        authored or adopted through the platform (get_products →
        create_media_buy → update_media_buy) — the platform sends instructions
        down. In both states the execution system remains the source of truth.
    GoalProgressTarget:
      oneOf:
        - type: object
          properties:
            kind:
              type: string
              enum:
                - cost_per
            value:
              type: number
          required:
            - kind
            - value
          additionalProperties: false
        - type: object
          properties:
            kind:
              type: string
              enum:
                - threshold_rate
            value:
              type: number
          required:
            - kind
            - value
          additionalProperties: false
        - type: object
          properties:
            kind:
              type: string
              enum:
                - per_ad_spend
            value:
              type: number
          required:
            - kind
            - value
          additionalProperties: false
        - type: object
          properties:
            kind:
              type: string
              enum:
                - maximize_value
          required:
            - kind
          additionalProperties: false
      description: >-
        A goal target: a cost per unit, a minimum rate per impression, a minimum
        return on ad spend, or maximise with no number.
      type: object
    DeliveryPace:
      type: object
      properties:
        flightElapsed:
          nullable: true
          description: >-
            Fraction of the WHOLE flight elapsed at the measured instant, 0 to
            1. This says where the buy is in its life; it is not what
            expectedSpend is computed from on a windowed read.
          type: number
        measuredFraction:
          nullable: true
          description: >-
            Fraction of the flight the reported spend actually covers. Equal to
            flightElapsed when the read covers the buy's whole life, smaller
            when it covers a selected window — and it is this, not
            flightElapsed, that expectedSpend and the verdict are measured over,
            so both sides of the ratio always describe the same interval.
          type: number
        expectedSpend:
          nullable: true
          description: >-
            The spend an even pace across the flight expects over the interval
            the reported spend covers.
          type: number
        actualSpend:
          nullable: true
          description: The delivered spend the expectation is compared against.
          type: number
        ratio:
          nullable: true
          description: >-
            actualSpend divided by expectedSpend; 1 sits exactly on the
            even-pace line.
          type: number
        spendPerDay:
          nullable: true
          description: >-
            Delivered spend per day of the measured interval — the number a
            "$200 a day" ask names.
          type: number
        budgetPerDay:
          nullable: true
          description: The daily rate an even pace across the whole flight implies.
          type: number
        currency:
          nullable: true
          type: string
        verdict:
          nullable: true
          description: >-
            How delivered spend compares with the even-pace line. Null whenever
            the evidence does not support a verdict; see verdictWithheld.
            `ahead` is neither praise nor alarm — it means the flight will
            exhaust early at this rate.
          type: string
          enum:
            - on_pace
            - behind
            - ahead
        verdictWithheld:
          nullable: true
          description: >-
            Why there is no pace verdict: no booked budget, no usable flight
            window, the flight has not started, the reporting window you asked
            for covers none of the flight (reading a recent window of a flight
            that ended months ago), the reported spend covers too little of the
            flight for the ratio to mean anything, or no delivery has been
            reported.
          type: string
          enum:
            - no_budget
            - no_flight
            - flight_not_started
            - window_outside_flight
            - too_short_a_window
            - spend_not_reported
      required:
        - flightElapsed
        - measuredFraction
        - expectedSpend
        - actualSpend
        - ratio
        - spendPerDay
        - budgetPerDay
        - currency
        - verdict
        - verdictWithheld
      additionalProperties: false
      description: >-
        Delivered spend measured against how much of the buy's flight has run,
        rather than against its budget alone.
    MediaBuyReporting:
      type: object
      properties:
        mediaBuyId:
          type: string
          description: Media buy identifier
        name:
          type: string
          description: Media buy name
        channelGroup:
          description: >-
            Campaign channel group that compiled into this media buy, or null
            for a legacy or ungrouped buy.
          nullable: true
          type: object
          properties:
            channelGroupId:
              type: string
            name:
              type: string
          required:
            - channelGroupId
            - name
          additionalProperties: false
        status:
          type: string
          description: Media buy status
        budget:
          nullable: true
          description: >-
            Total allocated budget for this media buy (sum of product budgets),
            GROSS (fee-inclusive — stored budgets are the buyer denomination
            since the gross-budgets flip). Legacy media buys created before fee
            terms were locked report their stored legacy (net) amount instead.
            Null if no budget set
          type: number
        metrics:
          $ref: '#/components/schemas/ReportingMetrics'
        deliveryFxConversion:
          description: >-
            FX conversion applied to delivery spend when the source reported in
            a different currency from the advertiser primary currency. Null when
            no conversion was needed.
          nullable: true
          type: object
          properties:
            fromCurrency:
              type: string
              description: >-
                ISO-4217 currency the delivery spend was denominated in: the
                currency the source reported, or — when the reported label
                contradicts an FX lock or booked spread-ledger leg — the
                currency the source settles in
            rate:
              type: number
              description: >-
                Multiplier applied to source spend to produce
                advertiser-currency spend (QUOTE per BASE, e.g. ZAR per USD)
            asOfDate:
              nullable: true
              description: >-
                UTC calendar date of the FX rate used. Null when source is
                settlement: identity denomination looks up no rate, so there is
                no rate date
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
            source:
              type: string
              enum:
                - booked
                - snapshot
                - settlement
              description: >-
                booked: rate locked in the spread ledger at buy time; snapshot:
                fx_rate_snapshots fallback on buy creation date; settlement: the
                source reported a currency it is not paid in, so the spend is
                denominated by its settlement currency (rate is always 1)
          required:
            - fromCurrency
            - rate
            - asOfDate
            - source
          additionalProperties: false
        goalProgress:
          description: >-
            Delivery judged against this buy's goal commitment (or the campaign
            goal when the buy predates commitments). Absent when the campaign
            has no goal and the buy no commitment.
          nullable: true
          allOf:
            - $ref: '#/components/schemas/GoalProgress'
        packages:
          type: array
          items:
            $ref: '#/components/schemas/PackageReporting'
          description: Package-level breakdown
      required:
        - mediaBuyId
        - name
        - status
        - budget
        - metrics
        - packages
      additionalProperties: false
      description: Media buy-level reporting metrics with package breakdown
    PackageReporting:
      type: object
      properties:
        packageId:
          type: string
          description: Package identifier
        productId:
          nullable: true
          description: Product identifier for this package
          type: string
        productName:
          nullable: true
          description: Human-readable product name for this package
          type: string
        metrics:
          $ref: '#/components/schemas/ReportingMetrics'
      required:
        - packageId
        - productId
        - productName
        - metrics
      additionalProperties: false
      description: Package-level reporting metrics
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key or access token

````

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