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

# Get Spending Analysis

> Get spending analysis for the authenticated user (v2, ClickHouse-backed).

Returns categorized spending breakdown with totals. Returns empty lists when no transactions match.
Reads from ClickHouse instead of Core API for improved performance and correctness.

**Double aggregation**: Use ``group_by=time_period`` with ``secondary_group_by=category``
or ``secondary_group_by=merchant`` to get a breakdown within each time period (top 10 + "Other").

The ``end_date`` is capped at today if it is in the future or omitted.

**Note:** Transactions from ``INVESTMENT``-type accounts (brokerage, crypto, IRA, etc.) are
always excluded — stock purchases, short sales, dividend reinvestments, and margin interest
are not personal spending. Passing an investment ``account_id`` in ``account_ids`` will
therefore return empty results for that account.

DEBIT transfers to investment platforms (Wealthfront, Robinhood, Fidelity, Schwab, Vanguard,
Coinbase, etc.) are also excluded even when the investment account itself is not connected.
The matching uses merchant name and description patterns, guarded against known false
positives (e.g. "Les Schwab Tires", "Fidelity Life Insurance"). CREDITs from these platforms
(withdrawals, dividends) are kept — they are real cashflow into the user's spending accounts.



## OpenAPI

````yaml GET /v2/users/spending
openapi: 3.1.0
info:
  title: Truv Public API
  description: >
    Read-only API for personal access token (PAT) users.


    ## Authentication


    Authenticate with `Authorization: Bearer <token>`. Tokens have a `pat_`
    prefix

    and are generated in the Truv web app under Settings → API keys.


    ## Available Endpoints


    This API exposes a subset of read-only endpoints for retrieving financial
    data,

    account links, and user profile information.
  version: 1.0.0
servers:
  - url: https://api.mytruv.com
    description: Production
security:
  - BearerAuth: []
tags:
  - name: users
    description: User profile — read-only access to the authenticated user's profile.
  - name: financial-data
    description: >-
      Financial data — balances, transactions, income, spending, liabilities,
      and balance history.
  - name: links
    description: >-
      Account links — list connected financial institutions and payroll
      providers.
paths:
  /v2/users/spending:
    get:
      tags:
        - financial-data
      summary: Get User Spending Analysis V2 Endpoint
      description: >-
        Get spending analysis for the authenticated user (v2,
        ClickHouse-backed).


        Returns categorized spending breakdown with totals. Returns empty lists
        when no transactions match.

        Reads from ClickHouse instead of Core API for improved performance and
        correctness.


        **Double aggregation**: Use ``group_by=time_period`` with
        ``secondary_group_by=category``

        or ``secondary_group_by=merchant`` to get a breakdown within each time
        period (top 10 + "Other").


        The ``end_date`` is capped at today if it is in the future or omitted.


        **Note:** Transactions from ``INVESTMENT``-type accounts (brokerage,
        crypto, IRA, etc.) are

        always excluded — stock purchases, short sales, dividend reinvestments,
        and margin interest

        are not personal spending. Passing an investment ``account_id`` in
        ``account_ids`` will

        therefore return empty results for that account.


        DEBIT transfers to investment platforms (Wealthfront, Robinhood,
        Fidelity, Schwab, Vanguard,

        Coinbase, etc.) are also excluded even when the investment account
        itself is not connected.

        The matching uses merchant name and description patterns, guarded
        against known false

        positives (e.g. "Les Schwab Tires", "Fidelity Life Insurance"). CREDITs
        from these platforms

        (withdrawals, dividends) are kept — they are real cashflow into the
        user's spending accounts.
      operationId: getSpendingAnalysisV2
      parameters:
        - name: group_by
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/GroupBy'
        - name: time_period
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/TimePeriod1'
        - name: link_id
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Link Id
        - name: start_date
          in: query
          required: false
          schema:
            anyOf:
              - type: string
                format: date
              - type: 'null'
            title: Start Date
        - name: end_date
          in: query
          required: false
          schema:
            anyOf:
              - type: string
                format: date
              - type: 'null'
            title: End Date
        - name: account_ids
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Account Ids
        - name: categories
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Categories
        - name: min_total_amount
          in: query
          required: false
          schema:
            anyOf:
              - type: number
              - type: string
                pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
              - type: 'null'
            default: '50.00'
            title: Min Total Amount
        - name: include_income
          in: query
          required: false
          schema:
            anyOf:
              - type: boolean
              - type: 'null'
            default: false
            title: Include Income
        - name: secondary_group_by
          in: query
          required: false
          schema:
            anyOf:
              - enum:
                  - category
                  - merchant
                type: string
              - type: 'null'
            title: Secondary Group By
      responses:
        '200':
          description: Spending analysis with optional double aggregation (v2).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SpendingAnalysisEnrichedResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    GroupBy:
      type: string
      enum:
        - category
        - merchant
        - time_period
      title: GroupBy
    TimePeriod1:
      type: string
      enum:
        - day
        - week
        - month
        - quarter
        - year
      title: TimePeriod1
    SpendingAnalysisEnrichedResponse:
      properties:
        spending:
          $ref: '#/components/schemas/SpendingData'
          description: Spending data from Truv API.
        summary:
          $ref: '#/components/schemas/SpendingSummary'
          description: Summary statistics from Truv API.
        request_id:
          type: string
          title: Request Id
          description: Unique request identifier.
        created_at:
          type: string
          title: Created At
          description: Analysis creation timestamp.
        by_time_period:
          anyOf:
            - items:
                $ref: '#/components/schemas/TimePeriodSpendingEnriched'
              type: array
            - type: 'null'
          title: By Time Period
          description: >-
            Time periods with category/merchant breakdown. Only present when
            group_by=time_period and secondary_group_by is set.
        total_income:
          anyOf:
            - type: string
              pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
            - type: 'null'
          title: Total Income
          description: >-
            Whole-window CREDIT total on the same hide-aware basis as the
            spending side (same hide, internal-transfer, and investment
            exclusions; scoped by link_id and account_ids). It is a whole-window
            figure and is NOT narrowed by the `categories` breakdown filter or
            the `include_income` flag. Null on the legacy v1 endpoint, which
            does not compute cash flow.
          examples:
            - '4345.00'
        total_expenses:
          anyOf:
            - type: string
              pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
            - type: 'null'
          title: Total Expenses
          description: >-
            Whole-window DEBIT total on the same basis as total_income. Pairs
            with total_income to derive the savings rate. Unlike
            summary.total_spending it is never signed against income and is not
            narrowed by the `categories` filter, so use this (not
            summary.total_spending) when displaying the savings rate. Null on
            the legacy v1 endpoint.
          examples:
            - '10550.00'
        savings_rate:
          anyOf:
            - type: string
              pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
            - type: 'null'
          title: Savings Rate
          description: >-
            (total_income minus total_expenses) as a percentage of total_income,
            one decimal place. Can be negative when expenses exceed income. Null
            when total_income is zero or negative (undefined) or on the legacy
            v1 endpoint.
          examples:
            - '-142.8'
      type: object
      required:
        - spending
        - summary
        - request_id
        - created_at
      title: SpendingAnalysisEnrichedResponse
      description: >-
        Spending analysis response with optional double aggregation.


        Wraps the Truv API response and adds `by_time_period` with breakdown
        when

        secondary_group_by is specified.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    SpendingData:
      properties:
        by_category:
          anyOf:
            - items:
                $ref: '#/components/schemas/CategorySpending'
              type: array
            - type: 'null'
          title: By Category
        by_merchant:
          anyOf:
            - items:
                $ref: '#/components/schemas/MerchantSpending'
              type: array
            - type: 'null'
          title: By Merchant
        by_time_period:
          anyOf:
            - items:
                $ref: '#/components/schemas/TimePeriodSpending'
              type: array
            - type: 'null'
          title: By Time Period
      additionalProperties: true
      type: object
      title: SpendingData
    SpendingSummary:
      properties:
        total_spending:
          type: string
          title: Total Spending
          examples:
            - '5100.00'
        average_daily_spending:
          type: string
          title: Average Daily Spending
          examples:
            - '170.00'
        average_monthly_spending:
          type: string
          title: Average Monthly Spending
          examples:
            - '5100.00'
        total_transactions:
          type: integer
          title: Total Transactions
          examples:
            - 249
        unique_merchants:
          type: integer
          title: Unique Merchants
          examples:
            - 3
        top_category:
          type: string
          title: Top Category
          examples:
            - Food & Dining
        top_merchant:
          type: string
          title: Top Merchant
          examples:
            - Whole Foods
      additionalProperties: true
      type: object
      required:
        - total_spending
        - average_daily_spending
        - average_monthly_spending
        - total_transactions
        - unique_merchants
        - top_category
        - top_merchant
      title: SpendingSummary
    TimePeriodSpendingEnriched:
      properties:
        start_date:
          anyOf:
            - type: string
            - type: 'null'
          title: Start Date
          description: Period start date (YYYY-MM-DD).
          examples:
            - '2024-01-01'
        end_date:
          type: string
          title: End Date
          description: Period end date (YYYY-MM-DD).
          examples:
            - '2024-01-31'
        total_amount:
          type: string
          pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
          title: Total Amount
          description: Total spending in this period.
          examples:
            - '1450.00'
        transaction_count:
          type: integer
          title: Transaction Count
          description: Number of transactions in this period.
          examples:
            - 52
        percentage_of_total:
          type: string
          pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
          title: Percentage Of Total
          description: Percentage of grand total spending.
          examples:
            - '31.7'
        trend:
          anyOf:
            - type: string
              pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
            - type: 'null'
          title: Trend
          description: Percentage change from previous period.
          examples:
            - '5.5'
        breakdown:
          items:
            $ref: '#/components/schemas/SpendingBreakdownItem'
          type: array
          title: Breakdown
          description: Breakdown by category or merchant. Top 10 + 'Other'.
      type: object
      required:
        - end_date
        - total_amount
        - transaction_count
        - percentage_of_total
        - breakdown
      title: TimePeriodSpendingEnriched
      description: Time period spending with optional breakdown by category or merchant.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    CategorySpending:
      properties:
        category:
          type: string
          title: Category
          examples:
            - Food & Dining
        total_amount:
          type: string
          title: Total Amount
          examples:
            - '1020.00'
        transaction_count:
          type: integer
          title: Transaction Count
          examples:
            - 36
        average_transaction:
          type: string
          title: Average Transaction
          examples:
            - '28.33'
        percentage_of_total:
          type: string
          title: Percentage Of Total
          examples:
            - '20.0'
        trend:
          anyOf:
            - type: string
            - type: 'null'
          title: Trend
          examples:
            - '5.0'
        largest_transaction:
          $ref: '#/components/schemas/LargestTransaction'
        subcategories:
          items:
            $ref: '#/components/schemas/Subcategory'
          type: array
          title: Subcategories
        time_series:
          items:
            $ref: '#/components/schemas/TimeSeriesPoint'
          type: array
          title: Time Series
      additionalProperties: true
      type: object
      required:
        - category
        - total_amount
        - transaction_count
        - average_transaction
        - percentage_of_total
        - largest_transaction
        - subcategories
        - time_series
      title: CategorySpending
    MerchantSpending:
      properties:
        merchant_name:
          type: string
          title: Merchant Name
          examples:
            - Whole Foods
        category:
          type: string
          title: Category
          examples:
            - Food & Dining
        total_amount:
          type: string
          title: Total Amount
          examples:
            - '408.00'
        transaction_count:
          type: integer
          title: Transaction Count
          examples:
            - 12
        average_transaction:
          type: string
          title: Average Transaction
          examples:
            - '34.00'
        percentage_of_total:
          type: string
          title: Percentage Of Total
          examples:
            - '20.0'
        trend:
          anyOf:
            - type: string
            - type: 'null'
          title: Trend
          examples:
            - '5.0'
        is_recurring:
          type: boolean
          title: Is Recurring
          examples:
            - true
        largest_transaction:
          $ref: '#/components/schemas/LargestTransaction'
        time_series:
          items:
            $ref: '#/components/schemas/TimeSeriesPoint'
          type: array
          title: Time Series
      additionalProperties: true
      type: object
      required:
        - merchant_name
        - category
        - total_amount
        - transaction_count
        - average_transaction
        - percentage_of_total
        - is_recurring
        - largest_transaction
        - time_series
      title: MerchantSpending
    TimePeriodSpending:
      properties:
        time_period:
          $ref: '#/components/schemas/TimePeriod'
          examples:
            - month
        start_date:
          anyOf:
            - type: string
            - type: 'null'
          title: Start Date
          examples:
            - '2025-10-02'
        end_date:
          type: string
          title: End Date
          examples:
            - '2025-11-01'
        total_amount:
          type: string
          title: Total Amount
          examples:
            - '408.00'
        transaction_count:
          type: integer
          title: Transaction Count
          examples:
            - 12
        average_transaction:
          type: string
          title: Average Transaction
          examples:
            - '34.00'
        percentage_of_total:
          type: string
          title: Percentage Of Total
          examples:
            - '20.0'
        trend:
          anyOf:
            - type: string
            - type: 'null'
          title: Trend
          examples:
            - '5.0'
        largest_transaction:
          $ref: '#/components/schemas/LargestTransaction'
      additionalProperties: true
      type: object
      required:
        - time_period
        - end_date
        - total_amount
        - transaction_count
        - average_transaction
        - percentage_of_total
        - largest_transaction
      title: TimePeriodSpending
    SpendingBreakdownItem:
      properties:
        name:
          type: string
          title: Name
          description: Category or merchant name.
          examples:
            - Food & Dining
        amount:
          type: string
          pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
          title: Amount
          description: Total spending amount.
          examples:
            - '650.00'
        transaction_count:
          type: integer
          title: Transaction Count
          description: Number of transactions.
          examples:
            - 24
        percentage:
          type: string
          pattern: ^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$
          title: Percentage
          description: Percentage of the period's total spending.
          examples:
            - '44.8'
      type: object
      required:
        - name
        - amount
        - transaction_count
        - percentage
      title: SpendingBreakdownItem
      description: >-
        A single item in the breakdown within a time period (category or
        merchant).
    LargestTransaction:
      properties:
        transaction_id:
          type: string
          maxLength: 32
          title: Transaction Id
        amount:
          type: string
          title: Amount
          examples:
            - '200.31'
        date:
          type: string
          format: date
          title: Date
          examples:
            - '2025-05-04'
        merchant_category_code:
          anyOf:
            - type: string
            - type: 'null'
          title: Merchant Category Code
          examples:
            - '5812'
        description:
          type: string
          title: Description
          examples:
            - Whole Foods Market
      additionalProperties: true
      type: object
      required:
        - transaction_id
        - amount
        - date
        - description
      title: LargestTransaction
    Subcategory:
      properties:
        name:
          type: string
          title: Name
          examples:
            - Groceries
        amount:
          type: string
          title: Amount
          examples:
            - '500.00'
        count:
          type: integer
          title: Count
          examples:
            - 15
      additionalProperties: true
      type: object
      required:
        - name
        - amount
        - count
      title: Subcategory
    TimeSeriesPoint:
      properties:
        start_date:
          anyOf:
            - type: string
            - type: 'null'
          title: Start Date
          examples:
            - '2025-10-16'
        end_date:
          type: string
          title: End Date
          examples:
            - '2025-10-16'
        amount:
          type: string
          title: Amount
          examples:
            - '31.27'
        count:
          type: integer
          title: Count
          examples:
            - 1
      additionalProperties: true
      type: object
      required:
        - end_date
        - amount
        - count
      title: TimeSeriesPoint
    TimePeriod:
      type: string
      enum:
        - day
        - week
        - month
        - quarter
        - year
      title: TimePeriod
      description: Time period unit
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: PAT
      description: >-
        Bearer authentication with a personal access token (prefix `pat_`).
        Generate tokens in the Truv web app under Settings → API keys.

````