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

# Get display performance

> The full performance stat set for one display over a period, including
average order value and, when the display has run an A/B test, per-variation
participants, conversions, and conversion rates.

Ask this per display rather than hunting the leaderboard: unlike
`/v1/reports/displays` it reports zeroed stats for a quiet display instead
of leaving it out. The display's own configuration — triggers, schedule,
status — is `/v1/displays/{id}`, keyed on the same identifier.

**Required scope:** `reports_read`




## OpenAPI

````yaml openapi/privy-api.yaml GET /reports/displays/{display_id}
openapi: 3.1.0
info:
  title: Privy API
  version: '1.0'
  description: >
    The Privy API lets you programmatically manage your contact list and read
    what you have set up in Privy.

    Create, update, unsubscribe, and remove contacts; report orders;

    and read your campaigns, flows, segments, orders, store products, coupon
    pools,

    performance reports, and account setup.
servers:
  - url: https://api.privy.com/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Account
    description: Retrieve information about the authenticated Privy account.
  - name: Contacts
    description: Manage your contact list.
  - name: Imports
    description: >-
      Read your contact import history — CSV uploads, connected-provider syncs,
      and SMS consent imports.
  - name: Campaigns
    description: >-
      Read your message campaigns — email and SMS newsletters, plus the messages
      your flows send.
  - name: Displays
    description: >-
      Read your on-site displays (popups, flyouts, banners, embedded forms,
      landing pages).
  - name: Coupons
    description: Read your coupon pools, their code inventory, and individual codes.
  - name: Reports
    description: >-
      Read performance reporting — signups, views, conversion rates, and
      attributed revenue — for your business, displays, and flows.
  - name: Flows
    description: Read your automation flows and their configuration.
  - name: Segments
    description: Read your customer segments and their membership.
  - name: Orders
    description: Report orders placed in your store and read your order history.
  - name: Products
    description: Read the product catalog and collections of your connected store.
  - name: Events
    description: Ingest custom events to trigger Flows and other automations.
paths:
  /reports/displays/{display_id}:
    get:
      tags:
        - Reports
      summary: Get display performance
      description: >
        The full performance stat set for one display over a period, including

        average order value and, when the display has run an A/B test,
        per-variation

        participants, conversions, and conversion rates.


        Ask this per display rather than hunting the leaderboard: unlike

        `/v1/reports/displays` it reports zeroed stats for a quiet display
        instead

        of leaving it out. The display's own configuration — triggers, schedule,

        status — is `/v1/displays/{id}`, keyed on the same identifier.


        **Required scope:** `reports_read`
      operationId: getDisplayReport
      parameters:
        - $ref: '#/components/parameters/AccountIdParam'
        - name: display_id
          in: path
          required: true
          description: >-
            The display's unique identifier (returned as `display_id` in report
            responses and `id` in display responses). Ids are opaque public
            strings — a numeric id from a Privy dashboard URL is not a valid API
            id and will 404; list displays and match by title instead.
          schema:
            type: string
          example: gk2P8Zw1Lq
        - $ref: '#/components/parameters/ReportPeriodParam'
        - $ref: '#/components/parameters/ReportStartDateParam'
        - $ref: '#/components/parameters/ReportEndDateParam'
      responses:
        '200':
          description: The display's performance over the resolved period.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/DisplayReportDetail'
              example:
                data:
                  display_id: gk2P8Zw1Lq
                  title: Summer Sale Popup
                  display_type: popup
                  status: live
                  period:
                    label: last_30_days
                    start_date: '2026-06-21'
                    end_date: '2026-07-20'
                  stats:
                    views:
                      value: 4200
                      unit: count
                    signups:
                      value: 310
                      unit: count
                    signup_rate:
                      value: 7.4
                      unit: percent
                    attributed_orders:
                      value: 28
                      unit: count
                    attributed_revenue:
                      value: 1840.5
                      unit: usd
                    average_order_value:
                      value: 65.73
                      unit: usd
                  ab_test:
                    name: Headline test
                    state: finished
                    goal: signup
                    total_participants: 9400
                    winner_variation_id: null
                    variations:
                      - id: abv_Jq8T2vY
                        display_id: gk2P8Zw1Lq
                        name: Original
                        is_control: true
                        traffic_ratio: 0.5
                        participants: 4700
                        conversions: 94
                        conversion_rate:
                          value: 2
                          unit: percent
                      - id: abv_Nk2P5rW
                        display_id: mP4tR9xK2b
                        name: Challenger
                        is_control: false
                        traffic_ratio: 0.5
                        participants: 4700
                        conversions: 129
                        conversion_rate:
                          value: 2.7
                          unit: percent
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/InsufficientScope'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '429':
          $ref: '#/components/responses/RateLimited'
      security:
        - bearerAuth: []
components:
  parameters:
    AccountIdParam:
      name: Privy-Account-Id
      in: header
      required: false
      description: >
        Target a subaccount instead of the main connected account.

        Pass a subaccount `id` from get_account's `subaccounts` list. Only
        direct subaccounts

        of the connected account are reachable — omit this for the main account
        itself.
      schema:
        type: string
      example: S1U2B3A4C5C6T7
    ReportPeriodParam:
      name: period
      in: query
      description: >-
        The date range to report over, resolved in the account's time zone. Pass
        `custom` together with `start_date` and `end_date`.
      schema:
        type: string
        enum:
          - last_7_days
          - last_30_days
          - last_90_days
          - this_month
          - last_month
          - custom
        default: last_30_days
      example: last_30_days
    ReportStartDateParam:
      name: start_date
      in: query
      description: >-
        Inclusive start of a `custom` period (ISO 8601 date). Required when
        `period=custom`, ignored otherwise.
      schema:
        type: string
        format: date
      example: '2026-06-01'
    ReportEndDateParam:
      name: end_date
      in: query
      description: >-
        Inclusive end of a `custom` period (ISO 8601 date). Required when
        `period=custom`, ignored otherwise. Custom periods are capped at 366
        days.
      schema:
        type: string
        format: date
      example: '2026-06-30'
  schemas:
    DisplayReportDetail:
      type: object
      description: >-
        One display's report: its identity, the period-scoped `stats` block, and
        A/B test results when the display has ever had a test.
      properties:
        display_id:
          type: string
          description: >-
            The display's unique identifier. Use this value in
            `/v1/displays/{id}`.
          example: gk2P8Zw1Lq
        title:
          type:
            - string
            - 'null'
          description: The display's name. `null` when the merchant never named it.
          example: Summer Sale Popup
        display_type:
          type:
            - string
            - 'null'
          description: >-
            The display's on-site shape (e.g. `popup`, `flyout`, `banner`,
            `bar`, `embedded_form`, `landing_page`).
          example: popup
        status:
          type: string
          description: >-
            The display's lifecycle status (e.g. `draft`, `scheduled`, `live`,
            `paused`, `ended`, `archived`).
          example: live
        period:
          $ref: '#/components/schemas/ReportPeriod'
        stats:
          description: >-
            The list shape's metrics plus `average_order_value`, which only this
            endpoint reports.
          allOf:
            - $ref: '#/components/schemas/DisplayReportStats'
            - type: object
              properties:
                average_order_value:
                  $ref: '#/components/schemas/ReportMetric'
        ab_test:
          description: >-
            The display's A/B test results, or `null` when it has never had one.
            Figures cover the test's whole life, so they will not line up with
            the surrounding `stats` block.
          oneOf:
            - $ref: '#/components/schemas/DisplayReportAbTest'
            - type: 'null'
    ReportPeriod:
      type: object
      description: |
        The resolved date range the report covers, inclusive, in the account's
        time zone. Every label except `last_month` ends today, so the last day
        of the range is still in progress: `last_7_days` is the six days before
        today plus today, `this_month` runs from the 1st through today, and
        `last_month` is the whole previous calendar month. Custom ranges cannot
        exceed 366 days.
      properties:
        label:
          type: string
          enum:
            - last_7_days
            - last_30_days
            - last_90_days
            - this_month
            - last_month
            - custom
          example: last_30_days
        start_date:
          type: string
          format: date
          example: '2026-06-21'
        end_date:
          type: string
          format: date
          example: '2026-07-20'
    DisplayReportStats:
      type: object
      description: |
        Performance metrics for one display over the report period. `views`
        counts impressions — one per time the display loaded on a visitor's
        screen, so a visitor who saw it on three pages counts three times — and
        `signups` counts form submissions, not distinct contacts. `signup_rate`
        is `signups` over `views`. `attributed_orders` and `attributed_revenue`
        credit the display under the same last-touch rule as the rest of
        Privy's reporting: an order counts when the contact's most recent
        engagement in the 7 days before it was an open or click on a message
        this display sends, such as its follow-up email or SMS. They are not a
        count of visitors who signed up here and later bought, which is the
        figure Privy's own display reporting shows — expect the two to differ,
        and expect a display that sends no follow-up message to report zero.
      properties:
        views:
          $ref: '#/components/schemas/ReportMetric'
        signups:
          $ref: '#/components/schemas/ReportMetric'
        signup_rate:
          $ref: '#/components/schemas/ReportMetric'
        attributed_orders:
          $ref: '#/components/schemas/ReportMetric'
        attributed_revenue:
          $ref: '#/components/schemas/ReportMetric'
    ReportMetric:
      type: object
      description: |
        A single report metric with its unit. `count` values are whole
        numbers, `percent` values are 0–100 with one decimal. Money metrics
        carry the account's lowercased ISO 4217 currency code as their unit
        (e.g. `usd`, `eur`, `jpy`) and are expressed in that currency's major
        units, two decimals. A rate whose denominator was zero reports 0, not
        null — so 0 does not distinguish "no activity" from "activity that
        never converted"; read the underlying counts to tell those apart.
      properties:
        value:
          type: number
          example: 42
        unit:
          type: string
          description: '`count`, `percent`, or a lowercased ISO 4217 currency code.'
          example: count
    DisplayReportAbTest:
      type: object
      description: |
        Results of the display's A/B test. `null` when the display has never
        had one; otherwise the display's currently running test, or its most
        recently created test once none is running. Figures cover the test's
        whole life and ignore the report period, so they will not line up with
        the surrounding `stats` block.
      properties:
        name:
          type: string
          description: The merchant's name for the test.
          example: Headline test
        state:
          type:
            - string
            - 'null'
          description: The test's lifecycle state (e.g. `draft`, `active`, `finished`).
          example: finished
        goal:
          type:
            - string
            - 'null'
          description: The event the test optimizes for.
          example: signup
        total_participants:
          type: integer
          description: >-
            Visitors assigned across every variation — the sum of the
            variations' `participants`.
          example: 9400
        winner_variation_id:
          type:
            - string
            - 'null'
          description: >-
            Currently always `null` — a merged test winner is not persisted.
            When populated it matches a variation's `id` in `variations`.
          example: null
        variations:
          type: array
          description: >-
            One entry per arm of the test. The order is not significant — use
            `is_control` to find the original and `id` to key rows.
          items:
            $ref: '#/components/schemas/DisplayReportAbTestVariation'
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - invalid_client
                - invalid_scope
                - unauthorized
                - insufficient_scope
                - paid_plan_required
                - api_access_required
                - not_found
                - no_connected_store
                - conflict
                - contacts_not_ready
                - validation_failed
                - rate_limited
                - store_unavailable
              example: validation_failed
            message:
              type: string
              example: One or more fields are invalid
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                    example: email
                  message:
                    type: string
                    example: is required
    DisplayReportAbTestVariation:
      type: object
      description: >-
        One arm of the display's A/B test — the control or a challenger — with
        its own traffic share and results. Figures cover the test's whole life
        and ignore the report period, like the enclosing `ab_test` block.
      properties:
        id:
          type: string
          description: >-
            Opaque, stable identifier for this variation row, prefixed `abv_`.
            Use it to key the `variations` array. No `/v1` resource resolves it
            — the prefix marks it as a report-local handle, not a lookup id.
            Unlike `display_id` it is always present, including for legacy
            variations with no display attached.
          example: abv_Jq8T2vY
        display_id:
          type:
            - string
            - 'null'
          description: >-
            Public id of the display this variation renders, resolvable at `GET
            /v1/displays/{id}`. For the control variation this is the display
            the report is about; each challenger is its own display. `null` only
            for legacy variations with no display attached — use `id` when a
            value is always required.
          example: gk2P8Zw1Lq
        name:
          type:
            - string
            - 'null'
          description: >-
            Merchant-assigned label for this variation. `null` when the
            variation was never named.
          example: Challenger
        is_control:
          type: boolean
          description: Whether this variation is the original (control) version.
          example: false
        traffic_ratio:
          type: number
          description: Fraction of traffic (0–1) assigned to this variation.
          example: 0.5
        participants:
          type: integer
          description: Distinct visitors assigned to this variation over the test's life.
          example: 4700
        conversions:
          type: integer
          description: >
            Goal events recorded for this variation — every occurrence, not
            distinct converters, so one visitor converting twice counts twice.
          example: 129
        conversion_rate:
          allOf:
            - $ref: '#/components/schemas/ReportMetric'
          description: >
            `conversions` over `participants`, 0 when the variation has no
            participants. It can exceed 100 because the numerator counts events
            and the denominator counts visitors.
  responses:
    Unauthorized:
      description: Missing or invalid bearer token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: unauthorized
              message: Bearer token is missing or invalid
    InsufficientScope:
      description: Token lacks the required scope for this endpoint.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: insufficient_scope
              message: Token does not have the required scope
    NotFound:
      description: >-
        The requested resource does not exist or does not belong to your
        account.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: not_found
              message: Not found
    ValidationFailed:
      description: One or more fields failed validation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: validation_failed
              message: One or more fields are invalid
              details:
                - field: email
                  message: is required
    RateLimited:
      description: Rate limit exceeded. Retry after the specified time.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
          example: 42
        X-RateLimit-Limit-Minute:
          description: Maximum requests allowed per minute.
          schema:
            type: integer
          example: 60
        X-RateLimit-Remaining-Minute:
          description: Requests remaining in the current minute window.
          schema:
            type: integer
          example: 0
        X-RateLimit-Reset-Minute:
          description: Unix timestamp when the minute window resets.
          schema:
            type: integer
          example: 1711929600
        X-RateLimit-Limit-Day:
          description: Maximum requests allowed per day.
          schema:
            type: integer
          example: 10000
        X-RateLimit-Remaining-Day:
          description: Requests remaining in the current day window.
          schema:
            type: integer
          example: 9500
        X-RateLimit-Reset-Day:
          description: Unix timestamp when the day window resets.
          schema:
            type: integer
          example: 1712016000
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: rate_limited
              message: Rate limit exceeded
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API token or OAuth access token
      description: >
        Send either an API token or an OAuth access token as

        `Authorization: Bearer <token>`. See the Authentication page for
        details.

````