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

# Revenue page datasets

> Billed net revenue (all classes; net = gross − tax after position discounts, credit notes negative) by country, by product and per customer with product sub-rows, the top products, and ARR at each month end: committed (MRR × 12) plus the trailing twelve-month variable revenue. One currency, never converted; `details` repeats the ARR series for every currency the organisation has.

Required permission: `analytics:read`.



## OpenAPI

````yaml assets/openapi-v2-finance.json get /api/analytics/finance/revenue
openapi: 3.0.3
info:
  title: Fynn Finanzberichte API
  version: 2026-09
  description: >-
    The finance reporting API returns the same figures as the finance pages of
    the app: MRR and its movements, Accounted MRR, cash, receivables, revenue,
    the customer base, month-end snapshots with their restatements and the Excel
    books. Every amount is an exact decimal string in one currency, never
    converted and never a float. Months are `YYYY-MM` in the time zone of the
    organisation.


    Authenticate every request with an API token of your organisation
    (`Authorization: Bearer api_...`). Reading needs `analytics:read`, taking a
    snapshot and changing the settings `analytics:write`. Every route also needs
    the finance reports to be enabled for the organisation (feature flag
    `analytics.advanced`); otherwise it answers 403 `feature-not-available`.
servers:
  - url: https://coreapi.io
    description: Production
  - url: https://preview.coreapi.io
    description: Sandbox
security:
  - ApiToken: []
tags:
  - name: Datensätze
    description: Page datasets and the MRR table.
  - name: Drill-downs und Hinweise
    description: Lines behind a cell and data-quality findings.
  - name: Snapshots
    description: Month-end snapshots and their versions.
  - name: Excel-Exporte
    description: Excel books of the finance pages.
  - name: Definitionen
    description: The versioned definitions catalogue with its changelog.
  - name: Einstellungen
    description: Organisation-wide settings of the finance figures.
paths:
  /api/analytics/finance/revenue:
    get:
      tags:
        - Datensätze
      summary: Revenue page datasets
      description: >-
        Billed net revenue (all classes; net = gross − tax after position
        discounts, credit notes negative) by country, by product and per
        customer with product sub-rows, the top products, and ARR at each month
        end: committed (MRR × 12) plus the trailing twelve-month variable
        revenue. One currency, never converted; `details` repeats the ARR series
        for every currency the organisation has.


        Required permission: `analytics:read`.
      operationId: getFinanceRevenue
      parameters:
        - name: from
          in: query
          description: >-
            First month (YYYY-MM, time zone of the organisation). Default: `to`
            minus 11 months.
          required: false
          schema:
            type: string
        - name: to
          in: query
          description: 'Last month (YYYY-MM). Default: the current month. At most 36 months.'
          required: false
          schema:
            type: string
        - name: currency
          in: query
          description: 'ISO-4217 code. Default: the default currency.'
          required: false
          schema:
            type: string
        - name: scope
          in: query
          description: >-
            Movement scope (committed ARR is scope-independent; accepted for a
            uniform query).
          required: false
          schema:
            type: string
            enum:
              - subscription
              - invoice_address
              - customer
              - organisation
        - name: segmentId
          in: query
          description: Analytics segment filter.
          required: false
          schema:
            type: string
            format: uuid
        - name: customerIds[]
          in: query
          description: Customer filter.
          required: false
          schema:
            type: array
            items:
              type: string
              format: uuid
        - name: productIds[]
          in: query
          description: Product filter.
          required: false
          schema:
            type: array
            items:
              type: string
              format: uuid
        - name: page
          in: query
          description: '`byCustomerAndProduct` only: page, starting at 1.'
          required: false
          schema:
            type: integer
            default: 1
            minimum: 1
        - name: pageSize
          in: query
          description: '`byCustomerAndProduct` only: customers per page.'
          required: false
          schema:
            type: integer
            default: 50
            maximum: 100
            minimum: 1
        - name: search
          in: query
          description: >-
            `byCustomerAndProduct` only: customer name, customer number or the
            name of one of the customer's products contains this text
            (case-insensitive, `%` and `_` are literal).
          required: false
          schema:
            type: string
            maxLength: 100
      responses:
        '200':
          description: The datasets.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FinanceRevenueView'
        '401':
          description: Missing or invalid authentication.
        '403':
          description: >-
            Missing permission `analytics:read` (`FRAMEWORK__ACCESS_DENIED`), or
            the finance reports are not enabled for the organisation (feature
            flag `analytics.advanced`, `type`
            https://fynn.dev/problems/feature-not-available).
          content:
            application/problem+json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Problem'
                  - $ref: '#/components/schemas/FeatureNotAvailableProblem'
        '422':
          description: >-
            Invalid query parameter. The body lists the offending parameters in
            `violations` (`propertyPath`, `message`, `code`).
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ValidationProblem'
      security:
        - ApiToken: []
components:
  schemas:
    FinanceRevenueView:
      description: >-
        Datasets of the revenue page: revenue by country, ARR at each month end
        (MRR × 12, the one ARR of every page) with the trailing twelve-month
        variable revenue as its own row, per-currency ARR details, invoiced
        revenue per month by class ("Umsatzdetails", reconciling to the revenue
        by country and by product), revenue by product, top products, and
        revenue per customer with product sub-rows. Revenue is invoiced net
        revenue of all classes (net = gross − tax after position discounts) by
        finalization month; credit notes and cancellations are negative in the
        month they were issued. Dunning fees are not revenue.
      properties:
        months:
          description: >-
            Months of the range (YYYY-MM, time zone of the organisation),
            ascending.
          type: array
          items:
            type: string
        byCountry:
          description: >-
            Net revenue per country of the invoice address in the range, largest
            first. `countryCode` is null when no country is known.
          type: array
          items:
            $ref: '#/components/schemas/CountryRevenueView'
        arrAtPeriodEnd:
          description: >-
            ARR at each month end in the selected currency (MRR × 12) and the
            trailing twelve-month variable revenue.
          allOf:
            - $ref: '#/components/schemas/ArrSeriesView'
        details:
          description: >-
            ARR and the trailing twelve-month variable revenue per currency the
            organisation has data in.
          type: array
          items:
            $ref: '#/components/schemas/ArrDetailView'
        byProduct:
          description: >-
            Net revenue per product and month; the product is null for positions
            without product.
          type: array
          items:
            $ref: '#/components/schemas/ProductSeriesView'
        topProducts:
          description: The ten products with the most net revenue in the range.
          type: array
          items:
            $ref: '#/components/schemas/ProductTotalView'
        byCustomerAndProduct:
          description: >-
            Page 1 (or the requested page) of the customer rows with product
            sub-rows and sparklines, as `{data, meta}`. Page turns should use
            `GET /api/analytics/finance/revenue/customers`, which returns the
            same shape without recomputing the other datasets.
          allOf:
            - $ref: '#/components/schemas/CustomerRevenuePageView'
        totals:
          description: 'Totals over the range: `net` (all revenue).'
          type: object
          additionalProperties:
            $ref: '#/components/schemas/MoneyView'
        meta:
          description: Calculation time, effective scope and currency, finding counts.
          allOf:
            - $ref: '#/components/schemas/FinanceMetaView'
        accountingClosed:
          description: >-
            Per month of `months`: the month's postings are closed in accounting
            (the ledger of the month is final). The analytics figures follow the
            source dates (finalization, payment and settlement date, service
            period) and can still change after the close; a record made after
            the close is a `POST_CLOSE_CHANGE` finding.
          type: array
          items:
            type: boolean
        revenueDetails:
          description: >-
            Invoiced net revenue per month by class ("Umsatzdetails") per
            currency the organisation has data in: recurring + one-off +
            variable = total. Over the range the total equals `totals.net`, the
            sum of `byCountry` and the sum of `byProduct` (same revenue lines,
            same filter).
          type: array
          items:
            $ref: '#/components/schemas/RevenueDetailView'
      type: object
    Problem:
      type: object
      description: >-
        Error body (problem+json). `type` is the error key, e.g.
        `ANALYTICS_MRR_FINANCIALS__SNAPSHOT_MONTH_NOT_ENDED`; further keys carry
        the parameters of the error.
      properties:
        status:
          type: integer
          example: 409
        type:
          type: string
          example: ANALYTICS_MRR_FINANCIALS__SNAPSHOT_MONTH_NOT_ENDED
        title:
          type: string
          example: An error occurred
        detail:
          type: string
          description: German sentence that can be shown to the user.
      required:
        - status
        - type
        - title
        - detail
      additionalProperties: true
    FeatureNotAvailableProblem:
      type: object
      description: >-
        403 body when the finance reports are not enabled for the organisation
        (feature flag `analytics.advanced`).
      properties:
        type:
          type: string
          enum:
            - https://fynn.dev/problems/feature-not-available
        title:
          type: string
          example: Feature not available
        detail:
          type: string
          example: >-
            The requested feature is not available. Please contact customer
            support.
        featureFlags:
          type: array
          items:
            type: string
          example:
            - analytics.advanced
      required:
        - type
        - title
        - detail
        - featureFlags
      additionalProperties: true
    ValidationProblem:
      type: object
      description: '422 body: one entry per rejected field in `violations`.'
      properties:
        status:
          type: integer
          example: 422
        type:
          type: string
          example: https://tools.ietf.org/html/rfc2616#section-10
        title:
          type: string
          example: Validation Failed
        detail:
          type: string
        violations:
          type: array
          items:
            $ref: '#/components/schemas/Violation'
      required:
        - status
        - type
        - violations
      additionalProperties: true
    CountryRevenueView:
      description: Net revenue of one country in the range.
      properties:
        countryCode:
          description: >-
            ISO 3166-1 alpha-2 country code of the invoice address; null when
            unknown.
          type: string
          example: DE
          nullable: true
        net:
          description: Net revenue.
          allOf:
            - $ref: '#/components/schemas/MoneyView'
        share:
          description: >-
            Share of the total net revenue as an exact decimal string with six
            places (`"0.250000"` = 25 %).
          type: string
          example: '0.250000'
      type: object
    ArrSeriesView:
      description: >-
        ARR at each month end: `total` = `committed` = MRR at the month end × 12
        (the one ARR of every page, without usage revenue); `variable` =
        variable revenue of the month and the eleven before it ("Variabel, 12
        Monate", `variable_12m`), shown as its own row and not added to ARR.
      properties:
        committed:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/MoneyView'
            nullable: true
        variable:
          type: array
          items:
            $ref: '#/components/schemas/MoneyView'
        total:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/MoneyView'
            nullable: true
      type: object
    ArrDetailView:
      description: ARR series of one currency.
      properties:
        currency:
          description: ISO-4217 currency code.
          type: string
          example: EUR
        committed:
          description: ARR (MRR at the month end × 12); equal to `arr`.
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/MoneyView'
            nullable: true
        variable:
          description: >-
            Trailing twelve-month variable revenue ("Variabel, 12 Monate"); not
            part of ARR.
          type: array
          items:
            $ref: '#/components/schemas/MoneyView'
        arr:
          description: ARR (MRR at the month end × 12).
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/MoneyView'
            nullable: true
        oneOff:
          description: >-
            Net one-off revenue billed in each month (signed: cancellations and
            credit notes negative); not part of ARR.
          type: array
          items:
            $ref: '#/components/schemas/MoneyView'
      type: object
    ProductSeriesView:
      description: Net revenue of one product per month.
      properties:
        product:
          description: The product; `id` and `name` are null for positions without product.
          allOf:
            - $ref: '#/components/schemas/RefView'
        values:
          description: Net revenue per month, aligned with `months`.
          type: array
          items:
            $ref: '#/components/schemas/MoneyView'
        total:
          description: Net revenue in the range.
          allOf:
            - $ref: '#/components/schemas/MoneyView'
      type: object
    ProductTotalView:
      description: Net revenue of one product in the range.
      properties:
        product:
          description: The product; `id` and `name` are null for positions without product.
          allOf:
            - $ref: '#/components/schemas/RefView'
        net:
          description: Net revenue in the range.
          allOf:
            - $ref: '#/components/schemas/MoneyView'
        share:
          description: >-
            Share of the total net revenue, exact decimal string with six
            places.
          type: string
          example: '0.125000'
      type: object
    CustomerRevenuePageView:
      description: >-
        One page of the revenue page's customer rows: customers ranked by net
        revenue in the range (descending; equal amounts by customer id, so the
        order is stable across pages), each with product sub-rows and a 12-month
        sparkline ending with the last month of the range.
      properties:
        data:
          description: Customers of this page.
          type: array
          items:
            $ref: '#/components/schemas/CustomerRevenueView'
        meta:
          description: >-
            `page`, `pageSize` and `total` (customers matching the filters and
            the search).
          allOf:
            - $ref: '#/components/schemas/PageMetaView'
      type: object
    MoneyView:
      description: >-
        A money amount. `amount` is an exact decimal string with two decimal
        places (net, excluding VAT, unless stated otherwise); `currency` is the
        ISO-4217 code.
      properties:
        amount:
          description: >-
            Exact decimal amount with two decimal places, dot as separator.
            Negative amounts carry a leading minus.
          type: string
          example: '1234.56'
        currency:
          description: ISO-4217 currency code.
          type: string
          example: EUR
      type: object
    FinanceMetaView:
      description: >-
        Context of a finance response: calculation time, the effective scope,
        currency and month range, and the finding counts.
      properties:
        asOf:
          description: >-
            When the figures were last calculated (ISO 8601). Null when no
            calculation exists yet.
          type: string
          format: date-time
          nullable: true
        buildId:
          description: >-
            Id of the calculation the figures come from. Null when no
            calculation exists yet.
          type: string
          nullable: true
        scope:
          description: >-
            Effective movement scope: the level on which new, expansion,
            contraction, lost and resurrecting are classified.
          type: string
          enum:
            - subscription
            - invoice_address
            - customer
            - organisation
          example: invoice_address
        currency:
          description: >-
            Effective currency (ISO-4217). Amounts are never converted between
            currencies.
          type: string
          example: EUR
        from:
          description: First month of the range (YYYY-MM, time zone of the organisation).
          type: string
          example: 2025-10
        to:
          description: Last month of the range (YYYY-MM, time zone of the organisation).
          type: string
          example: 2026-09
        findings:
          description: Number of data-quality findings of the calculation.
          allOf:
            - $ref: '#/components/schemas/FindingCountsView'
        filtersNotApplied:
          description: >-
            Datasets of this response that ignore the customer, product or
            segment filter because the underlying facts have no such dimension
            (for example receivables at past month ends).
          type: array
          items:
            type: string
        notSnapshotted:
          description: >-
            MRR table rows a month-end snapshot does not hold (invoice, cash and
            forecast figures). In the snapshot view they keep their current
            values. Empty when the range has no snapshot or a segment is
            applied.
          type: array
          items:
            type: string
          example:
            - one_off
            - accounted_mrr
            - cash_collected
        projectedFrom:
          description: >-
            First month of the range after the current one (YYYY-MM): from there
            the month-end stocks (open receivables, amounts owed to customers)
            carry today's open invoices forward, a projection as of today
            ("Prognose (Stand heute)"), not a fact. Null when the range ends in
            or before the current month.
          type: string
          example: 2026-10
          nullable: true
        forecast:
          description: >-
            Completeness of the invoice forecast ("Rechnungsprognose") in the
            range: `incomplete` with the number of subscriptions whose forecast
            failed. The forecast rows then show what the other subscriptions
            bring; they are marked "unvollständig", never read as 0.
          allOf:
            - $ref: '#/components/schemas/ForecastStatusView'
        build:
          description: >-
            The latest calculation attempt, also when it failed ("Berechnung
            abgebrochen"). Null when the organisation was never calculated.
          nullable: true
          allOf:
            - $ref: '#/components/schemas/BuildAttemptView'
        dataBuildId:
          description: >-
            Id of the calculation the figures come from (the last successful
            one). Differs from `build.buildId` when the latest attempt failed.
            Null when no calculation exists yet.
          type: string
          nullable: true
      type: object
    RevenueDetailView:
      description: >-
        Invoiced net revenue of one currency per month by class
        ("Umsatzdetails"): recurring + one-off + variable = total, each month
        and over the range. The same revenue lines as "Umsatz je Land" and
        "Umsatz je Produkt", so the totals over the range are equal. Documents
        count in the month they were finalized; credit notes and cancellations
        are negative in their own month. Dunning fees are not revenue.
      properties:
        currency:
          description: ISO-4217 currency code.
          type: string
          example: EUR
        recurring:
          description: Recurring positions ("Wiederkehrend"), per month.
          type: array
          items:
            $ref: '#/components/schemas/MoneyView'
        oneOff:
          description: One-off positions ("Einmalig"), per month.
          type: array
          items:
            $ref: '#/components/schemas/MoneyView'
        variable:
          description: >-
            Usage-based and percentage positions ("Variabel (Monat)"), per
            month.
          type: array
          items:
            $ref: '#/components/schemas/MoneyView'
        total:
          description: Recurring + one-off + variable ("Gesamt"), per month.
          type: array
          items:
            $ref: '#/components/schemas/MoneyView'
        totals:
          description: >-
            Sums over the range per row: `recurring`, `oneOff`, `variable`,
            `total`.
          type: object
          additionalProperties:
            $ref: '#/components/schemas/MoneyView'
      type: object
    Violation:
      type: object
      properties:
        propertyPath:
          type: string
          example: to
        message:
          type: string
          example: Der Zeitraum darf höchstens 36 Monate umfassen.
        code:
          type: string
          example: analytics.mrr_financials.range_too_long
      required:
        - propertyPath
        - message
        - code
    RefView:
      description: >-
        Reference to a customer, subscription, product or invoice: id, number
        and display name where they exist.
      properties:
        id:
          description: Id (UUID).
          type: string
          nullable: true
        number:
          description: >-
            Human-readable number (customer number, subscription number, invoice
            number).
          type: string
          nullable: true
        name:
          description: Display name.
          type: string
          nullable: true
      type: object
    CustomerRevenueView:
      description: Net revenue of one customer per month, with product sub-rows.
      properties:
        customer:
          description: The customer.
          allOf:
            - $ref: '#/components/schemas/RefView'
        values:
          description: Net revenue per month, aligned with `months`.
          type: array
          items:
            $ref: '#/components/schemas/MoneyView'
        total:
          description: Net revenue in the range.
          allOf:
            - $ref: '#/components/schemas/MoneyView'
        sparkline:
          description: >-
            Net revenue of the twelve months ending with the last month of the
            range, as exact decimal strings, oldest first.
          type: array
          items:
            type: string
            example: '1200.00'
        products:
          description: Product sub-rows.
          type: array
          items:
            $ref: '#/components/schemas/ProductSeriesView'
      type: object
    PageMetaView:
      description: Pagination of a list response.
      properties:
        page:
          description: Current page, starting at 1.
          type: integer
          example: 1
        pageSize:
          description: Maximum number of entries per page.
          type: integer
          example: 25
        total:
          description: Number of entries over all pages.
          type: integer
          example: 112
        sum:
          description: >-
            Sum of `amount` over all entries of all pages (drill-down lists
            only). It equals the value of the cell the list explains; for
            contraction and lost the lines carry the signed change, so their sum
            is the negative of the unsigned cell.
          nullable: true
          allOf:
            - $ref: '#/components/schemas/MoneyView'
        asOf:
          description: >-
            When the figures were last calculated (ISO 8601). Null when no
            calculation exists yet.
          type: string
          format: date-time
          nullable: true
      type: object
    FindingCountsView:
      description: Number of data-quality findings of the latest calculation per severity.
      properties:
        error:
          description: Findings that point at wrong numbers.
          type: integer
          example: 0
        warning:
          description: Findings that point at data that should be checked.
          type: integer
          example: 3
        info:
          description: Informational findings.
          type: integer
          example: 12
      type: object
    ForecastStatusView:
      description: >-
        Whether the invoice forecast of the range is complete: the billing
        forecast of a subscription can fail (finding `FORECAST_FAILED`), and
        that subscription is then missing from every forecast month. A forecast
        cell of an incomplete forecast is a lower bound, never "no invoices".
      properties:
        incomplete:
          description: >-
            True when the forecast of at least one subscription failed and the
            range contains forecast months (the current month or later).
          type: boolean
          example: false
        failedSubscriptions:
          description: >-
            Number of subscriptions whose billing forecast failed (0 when
            complete).
          type: integer
          example: 0
      type: object
    BuildAttemptView:
      description: >-
        The latest calculation attempt. When it failed, the figures still come
        from the last successful calculation (`meta.dataBuildId`, `meta.asOf`).
      properties:
        status:
          description: >-
            Outcome of the attempt: `succeeded`, or `failed` when it broke a
            consistency check and was cancelled (nothing of it was stored).
          type: string
          enum:
            - succeeded
            - failed
          example: failed
        builtAt:
          description: When the attempt started (ISO 8601).
          type: string
          format: date-time
        buildId:
          description: Id of the attempt. Equal to `meta.dataBuildId` when it succeeded.
          type: string
        failed:
          description: The broken checks; null unless `status` is `failed`.
          nullable: true
          allOf:
            - $ref: '#/components/schemas/BuildFailureView'
      type: object
    BuildFailureView:
      description: >-
        Why the latest calculation was cancelled: the consistency checks it
        broke. The rows are listed by the details metric `build_failure`.
      properties:
        invariants:
          description: >-
            Codes of the broken checks (sorted), e.g. `CASH_WITHIN_DOCUMENT`;
            `IDENTITY` for the MRR identity.
          type: array
          items:
            type: string
          example:
            - CASH_WITHIN_DOCUMENT
        rowCount:
          description: >-
            Number of rows that broke a check (complete, also above the listed
            rows).
          type: integer
          example: 5
        invoiceRowCount:
          description: >-
            Number of the listed rows that name an invoice. Equal to `rowCount`
            when every row is an invoice.
          type: integer
          example: 5
      type: object
  securitySchemes:
    ApiToken:
      type: http
      scheme: bearer
      description: >-
        API token of the organisation. Send it as Authorization: Bearer api_...
        The token is bound to exactly one organisation.

````