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

# List analytics metrics

> Returns the catalog of metrics the analytics query endpoint accepts.



## OpenAPI

````yaml openapi-admin.json GET /analytics/metrics
openapi: 3.1.0
info:
  title: Juo Admin API
  version: 1.0.0
  description: >-
    Programmatic access to subscription management for merchants.


    ## Core Resources


    - **Subscriptions** — the central entity. Belongs to a Customer, contains
    Items (product variants) and Discounts. Lifecycle: `active` → `paused` or
    `cancelled`; `paused` → `active` or `cancelled`; `cancelled` → `active` (via
    reactivate).

    - **Items** — subscription items (product variants) (quantity, price,
    billing/delivery policies).

    - **Discounts** — applied to subscriptions by discount code or manually
    (percentage or fixed amount, targeting subscription items or shipping).

    - **Customers** — customers who own subscriptions and payment methods.

    - **Products / Variants** — catalog products and variants that can be
    assigned to subscription plans.

    - **Schedules** — a read-only projection of upcoming billing orders, derived
    from subscription state, active schedule adjustments, and triggered
    workflows. **Schedule adjustments never modify the subscription** — they
    apply changes to upcoming orders matching the specified criteria (by cycle,
    date, or both), which may cover one or more orders. For permanent changes
    (billing frequency, items, payment method, delivery address), update the
    subscription directly.

    - **Workflows** — interactive customer-facing flows (retention, dunning,
    onboarding). Contain Steps connected by Transitions and produce Runs on each
    execution. Supports A/B experiment steps.


    ## Authentication


    Every request requires:

    - `X-Juo-Admin-Api-Key` header — the merchant's Admin API key.

    - `X-Tenant-ID` header — the store identifier (myshopify domain, e.g.
    `my-store.myshopify.com`).
servers:
  - url: https://api.juo.io/admin/v1
security:
  - AdminApiKey: []
  - BearerToken: []
tags:
  - name: subscriptions
    description: >-
      Recurring billing agreements with customers. Manage lifecycle (pause,
      resume, cancel, reactivate), items, and discounts.
  - name: customers
    description: Customers who own subscriptions. Create and update customer records.
  - name: products
    description: >-
      Products and variants linked to subscription plans. Manage catalog and
      plan assignments.
  - name: schedules
    description: >-
      Read-only view of upcoming billing orders generated from subscription
      state, schedule adjustments, and workflows. Use schedule adjustments for
      targeted changes to upcoming orders (scoped by cycle number, date, or
      both) — they never alter the subscription itself. For permanent changes
      (billing frequency, items, payment method), update the subscription
      directly.
  - name: workflows
    description: >-
      Interactive customer-facing flows for retention, dunning, and onboarding.
      Define steps, publish, and track execution runs and experiments.
  - name: analytics
    description: >-
      Time-series metrics over subscriptions, customers and orders. Read the
      metric catalog first: it states what each metric means, the approximations
      it carries, and which filters and group-by dimensions the metric will
      honour — an unsupported filter is a 400, not an empty result.
paths:
  /analytics/metrics:
    get:
      tags:
        - analytics
      summary: Describe the analytics metric catalog
      description: >-
        Returns every metric the analytics query endpoint accepts, with what the
        number means, the approximations it carries, and which filters and
        group-by dimensions it will honour. Intended to be read before building
        a query: a filter listed under `unsupported` is a 400, and one listed
        under `ignored` is silently not applied.
      parameters:
        - $ref: '#/components/parameters/TenantHeader'
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                properties:
                  metrics:
                    description: >-
                      Every metric the query endpoint accepts, with its filter
                      and group-by contract.
                    type: array
                    items:
                      type: object
                      properties:
                        key:
                          description: The metric key to send as `metric` on a query.
                          type: string
                        kind:
                          description: >-
                            Broad shape of the number: count, sum, unique, gauge
                            or ratio.
                          type: string
                        subject:
                          description: >-
                            The published API resource this number is about:
                            customers, subscriptions, subscription-items, orders
                            or order-items. Always equal to the part of `key`
                            before the colon. This is what one unit of the
                            metric means — `measuredOn` is the narrower question
                            of what one source row is, and the two differ
                            wherever a metric aggregates finer rows into a
                            coarser figure.
                          type: string
                        description:
                          description: What the number means.
                          type: string
                        assumptions:
                          description: >-
                            Every load-bearing approximation in the number, so a
                            caller can decide whether it matters to them. Never
                            empty.
                          type: array
                          items:
                            type: string
                        measuredOn:
                          description: >-
                            What one SOURCE ROW of this metric is: shop,
                            subscriber, subscription, subscription_item, order
                            or order_line. NOT what the number is about — read
                            `subject` for that. `order-items:units` is measured
                            on order_line rows and `orders:revenue` reports an
                            order figure over the same rows, so both report a
                            coarser figure than they measure. For a ratio this
                            is the denominator's row grain. Note the request
                            body's own `grain` is a different thing: the time
                            bucket.
                          type: string
                        additivity:
                          description: >-
                            Whether values sum across time buckets: `additive`,
                            `semi_additive` (use the bucket's last value) or
                            `non_additive` (re-aggregate from the underlying
                            set).
                          type: string
                        unit:
                          description: >-
                            `money_minor` means values are returned already
                            divided by 100. Absent for dimensionless numbers.
                          type: string
                        currencyConverted:
                          description: Whether an fx rate is applied at query time.
                          type: boolean
                        sourceModel:
                          description: >-
                            Internal identifier of the query shape that answers
                            this metric.
                          type: string
                        factSource:
                          description: >-
                            The declared fact source this metric reads, where it
                            reads one.
                          type: string
                        coveredFrom:
                          description: >-
                            Earliest instant this metric's source can be trusted
                            (ISO 8601). A range opened before it returns a
                            confident but incomplete answer.
                          type: string
                        groupBy:
                          description: Legal `dimensions` entries. Anything else is a 400.
                          type: array
                          items:
                            type: string
                        filter:
                          type: object
                          properties:
                            accepted:
                              description: >-
                                Dimension keys this metric compiles into its
                                query and applies, and which no declaration says
                                are empty for it. Three payload-shaped columns
                                (`event.product_id`, `event.variant_id`,
                                `event.owner_id`) are assigned for every event
                                type and have no coverage declaration, so they
                                appear here even where a given metric's rows may
                                not carry them — check the metric's
                                `assumptions`.
                              type: array
                              items:
                                type: string
                            ignored:
                              description: >-
                                Dimension keys accepted by the request schema
                                but NOT applied — reported back in
                                `meta.ignoredFilters`. A future release rejects
                                these instead, so prefer not to send them.
                              type: array
                              items:
                                type: string
                            unsupported:
                              description: >-
                                Dimension keys rejected with a 400: this
                                metric's source cannot be attributed to them.
                              type: array
                              items:
                                type: string
                            neverPopulated:
                              description: >-
                                Dimension keys the engine will apply but which
                                are NULL on every row this metric reads, because
                                the deriver never fills that column in for its
                                event types. A comparison other than `is_null`
                                matches nothing and a group-by returns one
                                all-NULL bucket, neither of which errors — so do
                                not offer these.
                              type: array
                              items:
                                type: string
                            conditional:
                              description: >-
                                Filters honoured only for requests of a
                                particular shape.
                              type: array
                              items:
                                type: object
                                properties:
                                  fields:
                                    description: The dimension keys this rule covers.
                                    type: array
                                    items:
                                      type: string
                                  requires:
                                    description: >-
                                      The request shape under which these fields
                                      are applied. Outside it they are ignored.
                                    type: string
                                required:
                                  - fields
                                  - requires
                            required:
                              description: >-
                                Dimension keys this metric cannot be queried
                                without. Omitting one is a 400.
                              type: array
                              items:
                                type: string
                          required:
                            - accepted
                            - ignored
                            - unsupported
                            - neverPopulated
                            - conditional
                            - required
                        grains:
                          description: >-
                            Legal `grain` values. Snapshot metrics accept only
                            `total`, having no history to bucket.
                          type: array
                          items:
                            type: string
                        rollups:
                          type: object
                          properties:
                            legal:
                              description: '`rollup` values the engine will not reject.'
                              type: array
                              items:
                                type: string
                            recommended:
                              description: >-
                                The rollup that answers the question this metric
                                asks. Stricter than `legal`: an `avg` over a
                                cumulative series returns a figure from the
                                middle of the window.
                              type: string
                          required:
                            - legal
                            - recommended
                        cohortEligible:
                          description: >-
                            Whether this metric can be requested with a `cohort`
                            specification.
                          type: boolean
                      required:
                        - key
                        - kind
                        - subject
                        - description
                        - assumptions
                        - measuredOn
                        - additivity
                        - currencyConverted
                        - sourceModel
                        - groupBy
                        - filter
                        - grains
                        - rollups
                        - cohortEligible
                required:
                  - metrics
        '400':
          description: >-
            Bad request — invalid input or violated business rule (e.g., wrong
            subscription status for the requested operation).
        '401':
          description: Unauthorized — missing, expired, or invalid API key.
        '403':
          description: Forbidden — authenticated but not permitted to access this resource.
        '404':
          description: >-
            Not found — the resource does not exist or belongs to a different
            tenant.
        '422':
          description: >-
            Unprocessable entity — well-formed request that fails semantic
            validation.
components:
  parameters:
    TenantHeader:
      name: X-Tenant-ID
      x-speakeasy-name-override: tenant
      x-speakeasy-globals-hidden: true
      in: header
      schema:
        type: string
      required: true
      description: >-
        Unique identifier of the tenant in the system (usually a store
        identifier)
  securitySchemes:
    AdminApiKey:
      type: apiKey
      name: X-Juo-Admin-Api-Key
      in: header
      description: >-
        Long-lived Admin API key issued from the Juo merchant portal. Pass as
        the `X-Juo-Admin-Api-Key` header.
    BearerToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Short-lived JWT minted via the merchant browser-session flow. Carries
        the authenticated staff identity so that API calls are attributed to the
        specific staff user in the activity log.

````