> ## 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.

# Customer base page datasets

> Key figures (active accounts, ARPA, NRR, GRR), net and gross revenue retention per month, the cohort triangle, customer concentration, account movements, lost MRR by cancellation reason and the segment comparison (all accounts, `segmentId`, `compareSegmentId`). Accounts are the accounts of the movement scope; a segment selects accounts by their customer.

Required permission: `analytics:read`.



## OpenAPI

````yaml assets/openapi-v2-finance.json get /api/analytics/finance/customers
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/customers:
    get:
      tags:
        - Datensätze
      summary: Customer base page datasets
      description: >-
        Key figures (active accounts, ARPA, NRR, GRR), net and gross revenue
        retention per month, the cohort triangle, customer concentration,
        account movements, lost MRR by cancellation reason and the segment
        comparison (all accounts, `segmentId`, `compareSegmentId`). Accounts are
        the accounts of the movement scope; a segment selects accounts by their
        customer.


        Required permission: `analytics:read`.
      operationId: getFinanceCustomers
      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. Default: the organisation setting.'
          required: false
          schema:
            type: string
            enum:
              - subscription
              - invoice_address
              - customer
              - organisation
        - name: segmentId
          in: query
          description: 'Analytics segment: only its customers.'
          required: false
          schema:
            type: string
            format: uuid
        - name: compareSegmentId
          in: query
          description: Second analytics segment for the comparison.
          required: false
          schema:
            type: string
            format: uuid
        - name: granularity
          in: query
          description: Cohorts per month (default) or per quarter.
          required: false
          schema:
            type: string
            enum:
              - month
              - quarter
      responses:
        '200':
          description: The datasets.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomersDatasetView'
        '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:
    CustomersDatasetView:
      description: >-
        Customer base page: key figures, retention, cohorts, concentration,
        account movements, churn by reason and segment comparison.
      properties:
        tenantName:
          description: Name of the organisation.
          type: string
        currency:
          description: Currency of every amount (ISO-4217).
          type: string
        asOf:
          description: Calculation time; null before the first calculation.
          type: string
          format: date-time
          nullable: true
        months:
          description: Months of the range (YYYY-MM), ascending.
          type: array
          items:
            type: string
        customers:
          description: The datasets.
          allOf:
            - $ref: '#/components/schemas/CustomerBaseView'
        granularity:
          description: Cohort granularity.
          type: string
          enum:
            - month
            - quarter
        segmentComparable:
          description: >-
            Fields of `segmentMetrics` that compare across segments of different
            size (rates and ARPA).
          type: array
          items:
            type: string
        meta:
          description: Calculation time, scope, currency, findings, filters not applied.
          allOf:
            - $ref: '#/components/schemas/FinanceMetaView'
      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
    CustomerBaseView:
      description: Datasets of the customer base page.
      properties:
        kpis:
          description: 'Key figures: active accounts, ARPA, NRR, GRR.'
          type: array
          items:
            $ref: '#/components/schemas/KpiTileView'
        retention:
          description: NRR and GRR per month.
          type: array
          items:
            $ref: '#/components/schemas/RetentionPointView'
        cohorts:
          description: Cohort triangle.
          type: array
          items:
            $ref: '#/components/schemas/CohortRowView'
        concentration:
          description: Concentration at the end of the range.
          allOf:
            - $ref: '#/components/schemas/ConcentrationView'
        logos:
          description: Account movements per month.
          type: array
          items:
            $ref: '#/components/schemas/LogoMonthView'
        churnReasons:
          description: Lost MRR by cancellation reason.
          allOf:
            - $ref: '#/components/schemas/ChurnReasonsView'
        segmentMetrics:
          description: All accounts, then the requested segment and the comparison segment.
          type: array
          items:
            $ref: '#/components/schemas/SegmentMetricsView'
      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
    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
    KpiTileView:
      description: >-
        One key figure tile: value of `asOfMonth`, change to the previous month
        and up to twelve points of history.
      properties:
        id:
          description: >-
            Stable id of the figure (`mrr`, `arr`, `accounted_mrr`, `net_new`,
            `quick_ratio`, `active`, `arpa`, `nrr`, `grr`, `net_cash`,
            `outstanding`, `overdue`, `dso`, `dso_12m`).
          type: string
          example: mrr
        title:
          description: German title.
          type: string
          example: MRR
        valueKind:
          description: >-
            How to format the value and the change: `money`, `rate` (0.125000 =
            12.5 %), `ratio`, `count`, `days`.
          type: string
          enum:
            - money
            - rate
            - ratio
            - count
            - days
        value:
          description: >-
            The value as an exact decimal string; null when it cannot be
            computed.
          type: string
          example: '12500.00'
          nullable: true
        delta:
          description: >-
            Change to the previous month in the same unit (for rates: the
            difference of the rates); null without a comparison.
          type: string
          example: '250.00'
          nullable: true
        better:
          description: Which direction is favourable.
          type: string
          enum:
            - up
            - down
        sparkline:
          description: Up to twelve values, oldest first, ending with the value.
          type: array
          items:
            type: string
            nullable: true
        caption:
          description: >-
            Reference shown under the value (`im Zeitraum`, `heute`); null when
            the value is the month at the end of the range.
          type: string
          nullable: true
        asOfMonth:
          description: >-
            Month the value belongs to (YYYY-MM): the month at the end of its
            series; for `heute` tiles the running month. On the recurring page
            the tiles show the last COMPLETE month by default and carry the
            running month in `current`.
          type: string
          example: 2026-08
          nullable: true
        monthComplete:
          description: >-
            False when `asOfMonth` is the running month (or later): the value is
            not final ("laufend"). True for an ended month.
          type: boolean
          example: true
          nullable: true
        current:
          description: >-
            The running month next to a tile that shows the last complete month
            (recurring page); null otherwise.
          nullable: true
          allOf:
            - $ref: '#/components/schemas/KpiCurrentView'
      type: object
    RetentionPointView:
      description: Net and gross revenue retention over twelve months.
      properties:
        month:
          description: Month (YYYY-MM).
          type: string
        nrr:
          description: >-
            NRR as rate (1.050000 = 105 %); null without a base twelve months
            earlier.
          type: string
          nullable: true
        grr:
          description: GRR as rate; null without a base.
          type: string
          nullable: true
        cohortAccounts:
          description: Accounts paying twelve months earlier.
          type: integer
        cohortMrr:
          description: Their MRR then; null without a base.
          type: string
          nullable: true
      type: object
    CohortRowView:
      description: >-
        One cohort: the accounts whose first paying month is the cohort month
        (or quarter).
      properties:
        cohort:
          description: First month of the cohort (YYYY-MM).
          type: string
        accounts:
          description: Accounts of the cohort.
          type: integer
        startMrr:
          description: MRR at age 0.
          type: string
        cells:
          description: Cells by age.
          type: array
          items:
            $ref: '#/components/schemas/CohortCellView'
      type: object
    ConcentrationView:
      description: Customer concentration at the end of a month.
      properties:
        month:
          description: Month (YYYY-MM).
          type: string
        total:
          description: Total MRR.
          type: string
        segments:
          description: Rank groups.
          type: array
          items:
            $ref: '#/components/schemas/ConcentrationSegmentView'
        top1Share:
          description: Share of the largest account.
          type: string
        top5Share:
          description: Share of the five largest accounts.
          type: string
        top10Share:
          description: Share of the ten largest accounts.
          type: string
        above5Count:
          description: Accounts with more than 5 % of the MRR.
          type: integer
        top:
          description: The ten largest accounts.
          type: array
          items:
            $ref: '#/components/schemas/ConcentrationEntryView'
      type: object
    LogoMonthView:
      description: Account movements of one month.
      properties:
        month:
          description: Month (YYYY-MM).
          type: string
        new:
          description: New accounts.
          type: integer
        resurrecting:
          description: Resurrected accounts.
          type: integer
        lost:
          description: Lost accounts.
          type: integer
        net:
          description: New + resurrected − lost.
          type: integer
        activeEop:
          description: Paying accounts at month end.
          type: integer
      type: object
    ChurnReasonsView:
      description: >-
        Lost MRR of the range by cancellation reason; reconciles to the lost
        movement.
      properties:
        total:
          description: Lost MRR of the range.
          type: string
        accounts:
          description: Lost accounts (per month).
          type: integer
        entries:
          description: Entries, largest first.
          type: array
          items:
            $ref: '#/components/schemas/ChurnReasonEntryView'
      type: object
    SegmentMetricsView:
      description: Figures of one segment for the comparison.
      properties:
        id:
          description: Segment id; `all` = every account.
          type: string
        name:
          description: Segment name.
          type: string
        mrr:
          description: MRR at the end of the range.
          type: string
        nrr:
          description: NRR at the end of the range.
          type: string
          nullable: true
        grr:
          description: GRR at the end of the range.
          type: string
          nullable: true
        churnRate:
          description: >-
            (contraction + lost) / MRR at period start, over the sums of the
            range.
          type: string
          nullable: true
        arpa:
          description: MRR per paying account at the end of the range.
          type: string
          nullable: true
        newAccounts:
          description: New accounts in the range.
          type: integer
        activeAccounts:
          description: Paying accounts at the end of the range.
          type: integer
      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
    KpiCurrentView:
      description: >-
        The running month of a key figure tile whose value shows the last
        complete month: the value so far and its change to the previous month.
      properties:
        asOfMonth:
          description: Month of the value (YYYY-MM), the running month.
          type: string
          example: 2026-09
        value:
          description: >-
            The value so far as an exact decimal string (unit as the tile); null
            when it cannot be computed.
          type: string
          example: '5279.33'
          nullable: true
        delta:
          description: >-
            Change to the previous month in the tile's unit; null where the tile
            compares complete months only (Accounted MRR) or without a
            comparison.
          type: string
          example: '1916.00'
          nullable: true
        monthComplete:
          description: 'Always false: the month has not ended.'
          type: boolean
          example: false
      type: object
    CohortCellView:
      description: One cell of the cohort triangle.
      properties:
        age:
          description: Months since the cohort month (0 = start).
          type: integer
        month:
          description: Month of the cell (YYYY-MM).
          type: string
        mrr:
          description: MRR of the cohort in that month.
          type: string
        retention:
          description: MRR / MRR at age 0 as rate.
          type: string
          nullable: true
      type: object
    ConcentrationSegmentView:
      description: Share of one rank group in the MRR.
      properties:
        key:
          description: 'Group: `top1`, `top2_5`, `top6_10`, `rest`.'
          type: string
          enum:
            - top1
            - top2_5
            - top6_10
            - rest
        label:
          description: German label.
          type: string
        amount:
          description: MRR of the group.
          type: string
        share:
          description: Share as rate; the four shares add up to exactly 1.
          type: string
        accounts:
          description: Accounts in the group.
          type: integer
      type: object
    ConcentrationEntryView:
      description: One of the ten largest accounts.
      properties:
        rank:
          description: Rank (1 = largest).
          type: integer
        customer:
          description: Customer of the account.
          allOf:
            - $ref: '#/components/schemas/RefView'
        mrr:
          description: MRR at month end.
          type: string
        share:
          description: Share of the total MRR as rate.
          type: string
        change:
          description: Change compared with three months earlier.
          type: string
      type: object
    ChurnReasonEntryView:
      description: Lost MRR of one cancellation reason.
      properties:
        code:
          description: >-
            Cancellation reason code; `pause` = paused, `voided` = voided
            subscription, null = no reason given.
          type: string
          nullable: true
        label:
          description: >-
            German label (the reason name of the organisation, `Pausiert`,
            `Annulliert`, `Ohne Angabe`).
          type: string
        amount:
          description: Lost MRR (positive).
          type: string
        accounts:
          description: Lost accounts (per month).
          type: integer
        share:
          description: Share of the lost MRR as rate; all shares add up to exactly 1.
          type: string
      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
    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
  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.

````