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

# List unified page metrics

> Returns the unified Audit page rollup. Page rows and summary are content-page subsets; searchConsole contains authoritative all-page project totals, current/prior coverage and source dates. GSC windows end at Pacific D-3. GSC columns are ranking evidence only when availability is measured or verified_zero. Partial coverage names the covered ranges; a delta requires both periods to be verified. Only 7, 30 and 90 day windows are accepted.



## OpenAPI

````yaml /openapi.json get /projects/{projectId}/pages/metrics
openapi: 3.1.0
info:
  title: DevTune API
  version: 2.0.0
  description: >-
    API for programmatic access to your AI visibility data, webhook
    subscriptions, and automation workflows. Use this API to integrate DevTune
    data into CI/CD pipelines, BI tools, AI agents, and operational systems.
servers:
  - url: https://devtune.ai/api/v2
    description: Production
security:
  - bearerAuth: []
paths:
  /projects/{projectId}/pages/metrics:
    get:
      summary: List unified page metrics
      description: >-
        Returns the unified Audit page rollup. Page rows and summary are
        content-page subsets; searchConsole contains authoritative all-page
        project totals, current/prior coverage and source dates. GSC windows end
        at Pacific D-3. GSC columns are ranking evidence only when availability
        is measured or verified_zero. Partial coverage names the covered ranges;
        a delta requires both periods to be verified. Only 7, 30 and 90 day
        windows are accepted.
      operationId: listUnifiedPageMetrics
      parameters:
        - name: projectId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: windowDays
          in: query
          schema:
            type: integer
            default: 30
            enum:
              - 7
              - 30
              - 90
          description: >-
            Fixed rolling window in days. Supported values are 7, 30, and 90.
            Defaults to 30.
        - name: cursor
          in: query
          schema:
            type: string
          description: Opaque cursor from the previous response.
        - name: pageSize
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
          description: Results per page. Capped at 100.
        - name: category
          in: query
          schema:
            type: string
        - name: sortKey
          in: query
          schema:
            type: string
        - name: sortDirection
          in: query
          schema:
            type: string
            enum:
              - asc
              - desc
            default: asc
      responses:
        '200':
          description: Unified page metrics
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/PageMetricsData'
                  meta:
                    $ref: '#/components/schemas/Meta'
                required:
                  - data
                  - meta
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          $ref: '#/components/responses/ForbiddenError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '429':
          $ref: '#/components/responses/RateLimitExceededError'
components:
  schemas:
    PageMetricsData:
      type: object
      properties:
        analyticsReportingContext:
          $ref: '#/components/schemas/AnalyticsReportingContext'
        searchConsole:
          $ref: '#/components/schemas/GscWindowPeriods'
        items:
          type: array
          items:
            $ref: '#/components/schemas/FlexibleRollupItem'
        pagination:
          $ref: '#/components/schemas/RollupCursorPagination'
        summary:
          $ref: '#/components/schemas/FlexibleRollupItem'
        windowDays:
          type: integer
          enum:
            - 7
            - 30
            - 90
      required:
        - items
        - pagination
        - summary
        - windowDays
        - searchConsole
    Meta:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        projectId:
          type: string
          format: uuid
    AnalyticsReportingContext:
      type: object
      description: >-
        Selected analytics provider provenance, full-window coverage, explicit
        daily gaps and AI-referred session metrics. PostHog duration and bounce
        are native metrics, not GA4 engagement.
      properties:
        comparisonCoverage:
          $ref: '#/components/schemas/ReferralWindowCoverage'
        quality:
          type: array
          items:
            type: object
            properties:
              connectionId:
                type: string
              domainCanonical:
                type: string
              day:
                type: string
                format: date
              sessions:
                $ref: '#/components/schemas/AnalyticsQuality'
              conversions:
                $ref: '#/components/schemas/AnalyticsQuality'
            required:
              - connectionId
              - domainCanonical
              - day
              - sessions
              - conversions
        comparisonQuality:
          type: array
          items:
            type: object
            properties:
              connectionId:
                type: string
              domainCanonical:
                type: string
              day:
                type: string
                format: date
              sessions:
                $ref: '#/components/schemas/AnalyticsQuality'
              conversions:
                $ref: '#/components/schemas/AnalyticsQuality'
            required:
              - connectionId
              - domainCanonical
              - day
              - sessions
              - conversions
        window:
          type: object
          properties:
            dateFrom:
              type: string
              format: date
            dateTo:
              type: string
              format: date
            previousDateFrom:
              type: string
              format: date
            previousDateTo:
              type: string
              format: date
          required:
            - dateFrom
            - dateTo
            - previousDateFrom
            - previousDateTo
        providers:
          type: array
          items:
            type: object
            properties:
              provider:
                type: string
                enum:
                  - ga4
                  - posthog
              domainCanonical:
                type: string
              connectionId:
                type: string
              definitionHash:
                type:
                  - string
                  - 'null'
              generation:
                type: integer
              status:
                type: string
              reportingTimezone:
                type: string
              reportSnapshot:
                type:
                  - object
                  - 'null'
                description: >-
                  Published report freshness and replacement state. While
                  replacing, definitionHash and generation identify the retained
                  report; pending fields identify collection work. Publication
                  waits for both supported 90-day windows. Older history can
                  still have explicit coverage gaps.
                properties:
                  state:
                    type: string
                    enum:
                      - collecting
                      - replacing
                      - current
                  syncedAt:
                    type:
                      - string
                      - 'null'
                  throughDate:
                    type:
                      - string
                      - 'null'
                  replacementWindowEnd:
                    type:
                      - string
                      - 'null'
                  pendingDefinitionHash:
                    type:
                      - string
                      - 'null'
                  pendingGeneration:
                    type: integer
                required:
                  - state
                  - syncedAt
                  - throughDate
                  - replacementWindowEnd
                  - pendingDefinitionHash
                  - pendingGeneration
            required:
              - provider
              - domainCanonical
              - connectionId
              - definitionHash
              - generation
              - status
              - reportingTimezone
        coverage:
          $ref: '#/components/schemas/ReferralWindowCoverage'
        gaps:
          type: array
          items:
            type: object
            properties:
              domainCanonical:
                type: string
              day:
                type: string
                format: date
              reason:
                type: string
            required:
              - domainCanonical
              - day
              - reason
        nativeMetrics:
          type: array
          items:
            type: object
            properties:
              provider:
                type: string
                enum:
                  - ga4
                  - posthog
              domainCanonical:
                type: string
              averageSessionDurationSeconds:
                type:
                  - number
                  - 'null'
              bounceRate:
                type:
                  - number
                  - 'null'
              engagementRate:
                type:
                  - number
                  - 'null'
              averageEngagementSeconds:
                type:
                  - number
                  - 'null'
            required:
              - provider
              - domainCanonical
              - averageSessionDurationSeconds
              - bounceRate
              - engagementRate
              - averageEngagementSeconds
      required:
        - window
        - providers
        - coverage
        - gaps
        - nativeMetrics
    GscWindowPeriods:
      type: object
      required:
        - current
        - prior
        - delta
      properties:
        current:
          $ref: '#/components/schemas/GscWindowPeriod'
        prior:
          $ref: '#/components/schemas/GscWindowPeriod'
        delta:
          oneOf:
            - type: 'null'
            - type: object
              properties:
                clicks:
                  type: integer
                impressions:
                  type: integer
          description: >-
            Absolute change in project totals, present only when both periods
            are verified.
    FlexibleRollupItem:
      type: object
      additionalProperties: true
      description: >-
        A projected row from the same bounded rollup used by the corresponding
        DevTune application surface.
    RollupCursorPagination:
      type: object
      properties:
        hasMore:
          type: boolean
        nextCursor:
          type:
            - string
            - 'null'
        pageSize:
          type: integer
          minimum: 1
          maximum: 100
        totalCount:
          type: integer
          minimum: 0
      required:
        - hasMore
        - nextCursor
        - pageSize
        - totalCount
    Error:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
        status:
          type: integer
      required:
        - error
        - message
        - status
    ReferralWindowCoverage:
      type: object
      additionalProperties: false
      description: >-
        Coverage of session and conversion-event counts across the current and
        previous reporting windows. False means observed counts may be partial
        or unavailable. Compare periods only when both flags for that metric are
        true; these flags apply to overview, engine and landing-page counts.
      properties:
        sessionsCurrent:
          type: boolean
        sessionsPrevious:
          type: boolean
        conversionsCurrent:
          type: boolean
        conversionsPrevious:
          type: boolean
      required:
        - sessionsCurrent
        - sessionsPrevious
        - conversionsCurrent
        - conversionsPrevious
    AnalyticsQuality:
      type: object
      description: >-
        Import continuity, observed tracking and attribution completeness are
        independent. Attributed partial counts are lower bounds; complete is
        required for comparisons and inferred zero.
      properties:
        configured:
          type: boolean
        importedDays:
          type: integer
        expectedDays:
          type: integer
        importsComplete:
          type: boolean
        trackingObserved:
          type: boolean
        attributionGapOccurrences:
          type: number
        noSiteVisitOccurrences:
          type: number
          description: >-
            Selected conversion events with no site visit, such as events sent
            from a server. They cannot be attributed to a landing page or AI
            referral, so they are not counted in attributionGapOccurrences and
            do not make conversions incomplete. Always 0 for sessions.
        attributionComplete:
          type: boolean
        complete:
          type: boolean
        reasons:
          type: array
          items:
            type: string
      required:
        - configured
        - importedDays
        - expectedDays
        - importsComplete
        - trackingObserved
        - attributionGapOccurrences
        - attributionComplete
        - complete
        - reasons
    GscWindowPeriod:
      type: object
      required:
        - aggregates
        - window
      properties:
        aggregates:
          type: object
          properties:
            clicks:
              type:
                - integer
                - 'null'
            impressions:
              type:
                - integer
                - 'null'
            ctr:
              type:
                - number
                - 'null'
            avgPosition:
              type:
                - number
                - 'null'
            measurement:
              $ref: '#/components/schemas/GscMeasurement'
        window:
          type: object
          properties:
            days:
              type: integer
              enum:
                - 7
                - 30
                - 90
            dateFrom:
              type: string
              format: date
            dateTo:
              type: string
              format: date
    GscMeasurement:
      type: object
      required:
        - availability
        - status
        - isCurrent
        - asOfDate
        - explanation
        - contributors
        - coveredRanges
        - storedEvidence
        - sourceDateFrom
        - sourceDateTo
        - finalityBoundary
      properties:
        availability:
          type: string
          enum:
            - unavailable
            - partial
            - verified_zero
            - measured
        status:
          type: string
          enum:
            - unmeasured
            - measured
          description: Compatibility field. Use availability when reporting evidence.
        isCurrent:
          type: boolean
          description: >-
            False when serving a retained publication after invalidation or
            source-boundary aging, or before first publication.
        asOfDate:
          type:
            - string
            - 'null'
          format: date-time
          description: Timestamp of the published source snapshot, when available.
        explanation:
          type: string
        coverageFrom:
          type:
            - string
            - 'null'
          format: date
        coverageThrough:
          type:
            - string
            - 'null'
          format: date
        sourceDateFrom:
          type:
            - string
            - 'null'
          format: date
        sourceDateTo:
          type:
            - string
            - 'null'
          format: date
        finalityBoundary:
          type:
            - string
            - 'null'
          format: date
          description: >-
            Published Pacific finality boundary, shared by current and prior
            periods. A retained snapshot keeps its original boundary.
        contributors:
          type: array
          items:
            type: object
            additionalProperties: true
        coveredRanges:
          type: array
          description: >-
            Clipped verified ranges per contributor. Overlap does not establish
            full project coverage.
          items:
            type: object
            properties:
              connectionId:
                type:
                  - string
                  - 'null'
              dateFrom:
                type: string
                format: date
              dateTo:
                type: string
                format: date
        storedEvidence:
          type: array
          description: >-
            Stored row-presence bounds, including legacy and historical
            generations. Excluded from verified totals.
          items:
            type: object
            additionalProperties: true
  responses:
    BadRequestError:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    UnauthorizedError:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ForbiddenError:
      description: Forbidden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFoundError:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimitExceededError:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  headers:
    X-RateLimit-Limit:
      description: Maximum requests per window
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests remaining in current window
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Unix timestamp when the window resets
      schema:
        type: integer
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key with dtk_live_ prefix. Obtain it from API Keys in the account
        sidebar. New keys start with all supported scopes selected for the
        chosen project, and you can narrow them to specific read/write scopes as
        needed.

````

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