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

# Summarise cash flow

> What the cash flow screen shows, decomposed, per period bucket and at most one more
dimension. Give `period`, or both `from` and `to`.

Each period has an actual half and a forecast half. The actual half is the
transactions dated in the period, counted as `/transactions/summary` counts them:
transfers between the workspace's own accounts and excluded movements are left out,
and split transactions count through their pieces. The forecast half is the remaining
amount of the unrealised forecasts dated in the period. A partly matched forecast
counts only what is still expected, and its linked transactions count as actuals.
`inflow`, `outflow` and `net` add the two halves and equal the screen.

Forecasts dated before today and still unrealised are overdue. They are left out of
the rows unless `include_overdue=true`. `totals.overdue_inflow` and `totals.overdue_outflow`
always report the remaining amount of the overdue forecasts the rows did not count.

Amounts convert to `currency` at the rate of each movement's own date. Buckets are
calendar aligned and clipped to the window. `totals` covers the whole window.

Rows grouped by period alone also carry the period's starting balance, opened
accounts, transfers, excluded movements and final balance. The final balance of a
future period is the projected balance. Those five are `null` when `group_by` or
`direction` is given.

A `bank_id` or `account_id` filter narrows the actual half and the balances, never the
forecasts, which have no account and always cover the whole workspace. A `bank_id`
that matches no account returns the empty result: no rows and zero totals.
`group_by=account` is rejected with 400 for the same reason.

Grouped rows are ordered by absolute `net`, largest first. A period keeps at most 50
groups; the rest fold into one row labelled `other`. Transactions and forecasts with
no counterparty or no label fall in a `none` row, and one with several labels counts
once per label. Here `category_id` also covers subcategories.

Filters combine with AND; a filter that takes a list combines its values with OR.

**Cash flow per month for the next quarter**

```http
GET /cash-flow/summary?period=next_quarter&interval=month
```

**Expected inflows per counterparty next month**

```http
GET /cash-flow/summary?period=next_month&group_by=counterparty&direction=inflow
```




## OpenAPI

````yaml /openapi/v1.yaml get /cash-flow/summary
openapi: 3.1.0
info:
  title: ThinkOut API
  version: '1.0'
  description: >
    Read access to the data of a ThinkOut workspace.


    Every endpoint in version 1 is a `GET`. Lists share one envelope and page
    with a cursor

    wherever they can grow. Every response carries `X-RateLimit-Limit`,
    `X-RateLimit-Remaining`

    and `X-RateLimit-Reset`.


    Version 1 changes additively: new endpoints, optional parameters, response
    fields and enum

    values can appear at any time. Tolerate unknown fields and never treat an
    enum as closed.
  contact:
    name: ThinkOut developer support
    url: https://developers.thinkout.io/guides/support
servers:
  - url: https://api.thinkout.io/v1
security:
  - apiKey: []
tags:
  - name: Banks
    description: The workspace's bank connections and the state of each one.
  - name: Accounts
    description: Manual, bank-synced and delegated accounts with computed balances.
  - name: Transactions
    description: Booked and pending movements on the workspace's accounts.
  - name: Categories
    description: The workspace category tree, split by direction and business activity.
  - name: Counterparties
    description: Customers and suppliers that transactions and forecasts are attributed to.
  - name: Labels
    description: Free-form tags grouped by label type.
  - name: Forecasts
    description: Planned inflows and outflows and the transactions that realised them.
  - name: Reports
    description: >-
      Totals rather than rows. Summaries over transactions, forecasts and cash
      flow, and balances per account.
paths:
  /cash-flow/summary:
    get:
      tags:
        - Reports
      summary: Summarise cash flow
      description: >
        What the cash flow screen shows, decomposed, per period bucket and at
        most one more

        dimension. Give `period`, or both `from` and `to`.


        Each period has an actual half and a forecast half. The actual half is
        the

        transactions dated in the period, counted as `/transactions/summary`
        counts them:

        transfers between the workspace's own accounts and excluded movements
        are left out,

        and split transactions count through their pieces. The forecast half is
        the remaining

        amount of the unrealised forecasts dated in the period. A partly matched
        forecast

        counts only what is still expected, and its linked transactions count as
        actuals.

        `inflow`, `outflow` and `net` add the two halves and equal the screen.


        Forecasts dated before today and still unrealised are overdue. They are
        left out of

        the rows unless `include_overdue=true`. `totals.overdue_inflow` and
        `totals.overdue_outflow`

        always report the remaining amount of the overdue forecasts the rows did
        not count.


        Amounts convert to `currency` at the rate of each movement's own date.
        Buckets are

        calendar aligned and clipped to the window. `totals` covers the whole
        window.


        Rows grouped by period alone also carry the period's starting balance,
        opened

        accounts, transfers, excluded movements and final balance. The final
        balance of a

        future period is the projected balance. Those five are `null` when
        `group_by` or

        `direction` is given.


        A `bank_id` or `account_id` filter narrows the actual half and the
        balances, never the

        forecasts, which have no account and always cover the whole workspace. A
        `bank_id`

        that matches no account returns the empty result: no rows and zero
        totals.

        `group_by=account` is rejected with 400 for the same reason.


        Grouped rows are ordered by absolute `net`, largest first. A period
        keeps at most 50

        groups; the rest fold into one row labelled `other`. Transactions and
        forecasts with

        no counterparty or no label fall in a `none` row, and one with several
        labels counts

        once per label. Here `category_id` also covers subcategories.


        Filters combine with AND; a filter that takes a list combines its values
        with OR.


        **Cash flow per month for the next quarter**


        ```http

        GET /cash-flow/summary?period=next_quarter&interval=month

        ```


        **Expected inflows per counterparty next month**


        ```http

        GET
        /cash-flow/summary?period=next_month&group_by=counterparty&direction=inflow

        ```
      operationId: summariseCashFlow
      parameters:
        - $ref: '#/components/parameters/period'
        - name: from
          in: query
          description: >-
            First day of the window, inclusive. Required with `to` unless
            `period` is given.
          schema:
            type: string
            format: date
        - name: to
          in: query
          description: >-
            Last day of the window, inclusive. Required with `from` unless
            `period` is given.
          schema:
            type: string
            format: date
        - $ref: '#/components/parameters/interval'
        - name: group_by
          in: query
          description: >-
            A second dimension to group by, alongside the period bucket. Omit it
            for one row per period.
          schema:
            $ref: '#/components/schemas/CashFlowGroupDimension'
        - $ref: '#/components/parameters/currency'
        - $ref: '#/components/parameters/bank_id'
        - $ref: '#/components/parameters/account_id'
        - $ref: '#/components/parameters/category_id'
        - $ref: '#/components/parameters/label_id'
        - $ref: '#/components/parameters/counterparty_id'
        - $ref: '#/components/parameters/direction'
        - $ref: '#/components/parameters/activity'
        - name: include_overdue
          in: query
          description: >-
            Whether overdue forecasts, those dated before today and still
            unrealised, count in the rows of the periods they fall in. Off, they
            only appear in `totals.overdue_inflow` and `totals.overdue_outflow`.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: The summary.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashFlowSummary'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          $ref: '#/components/responses/RequestTooLarge'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    period:
      name: period
      in: query
      description: >-
        A named window, resolved against the workspace's local day and echoed in
        the response. Takes precedence over `from` and `to`.
      schema:
        $ref: '#/components/schemas/PeriodMacro'
    interval:
      name: interval
      in: query
      description: The period bucket rows are grouped into.
      schema:
        $ref: '#/components/schemas/Interval'
    currency:
      name: currency
      in: query
      description: >-
        Currency to report in. Defaults to the workspace currency. An unknown
        code is rejected.
      schema:
        $ref: '#/components/schemas/Currency'
    bank_id:
      name: bank_id
      in: query
      description: >-
        Only rows on the accounts fed by these bank connections. Comma-separated
        for several.
      style: form
      explode: false
      schema:
        type: array
        items:
          type: string
          format: uuid
    account_id:
      name: account_id
      in: query
      description: Only rows on these accounts. Comma-separated for several.
      style: form
      explode: false
      schema:
        type: array
        items:
          type: string
          format: uuid
    category_id:
      name: category_id
      in: query
      description: >
        Only rows in these categories. Comma-separated for several. On
        `/transactions` this

        also matches a split transaction whose pieces are in one of them.
        Subcategories are

        included only on the summaries.
      style: form
      explode: false
      schema:
        type: array
        items:
          type: string
          format: uuid
    label_id:
      name: label_id
      in: query
      description: >-
        Only rows carrying at least one of these labels. Comma-separated for
        several.
      style: form
      explode: false
      schema:
        type: array
        items:
          type: string
          format: uuid
    counterparty_id:
      name: counterparty_id
      in: query
      description: >-
        Only rows attributed to these counterparties. Comma-separated for
        several.
      style: form
      explode: false
      schema:
        type: array
        items:
          type: string
          format: uuid
    direction:
      name: direction
      in: query
      schema:
        $ref: '#/components/schemas/Direction'
    activity:
      name: activity
      in: query
      description: >-
        Only rows whose category sits in these cash flow statement sections.
        Comma-separated for several.
      style: form
      explode: false
      schema:
        type: array
        items:
          $ref: '#/components/schemas/Activity'
  schemas:
    CashFlowGroupDimension:
      type: string
      description: >-
        A dimension to group cash flow rows by, alongside the period bucket.
        There is no `account`, because forecasts have none.
      enum:
        - category
        - counterparty
        - label
        - activity
        - direction
    CashFlowSummary:
      type: object
      required:
        - object
        - period
        - conversion
        - group_by
        - bank_ids
        - account_ids
        - forecast_scope
        - include_overdue
        - has_data
        - totals
        - data
      properties:
        object:
          type: string
          const: cash_flow_summary
        period:
          $ref: '#/components/schemas/ResolvedPeriod'
        conversion:
          $ref: '#/components/schemas/Conversion'
        group_by:
          oneOf:
            - $ref: '#/components/schemas/CashFlowGroupDimension'
            - type: 'null'
        bank_ids:
          type: array
          description: The `bank_id` filter echoed, empty when none was given.
          items:
            type: string
            format: uuid
        account_ids:
          type: array
          description: The `account_id` filter echoed, empty when none was given.
          items:
            type: string
            format: uuid
        forecast_scope:
          type: string
          const: workspace
          description: >-
            What the forecast half and the overdue totals cover. Always the
            whole workspace: a forecast has no account, so `bank_ids` and
            `account_ids` narrow only the actual half and the balances.
        include_overdue:
          type: boolean
          description: Whether overdue forecasts counted in the rows, as requested.
        has_data:
          type: boolean
          description: '`false` when no transaction and no forecast matched.'
        totals:
          $ref: '#/components/schemas/CashFlowSummaryTotals'
        data:
          type: array
          items:
            $ref: '#/components/schemas/CashFlowSummaryRow'
    PeriodMacro:
      type: string
      description: >-
        A named window resolved on the server. `last_30_days` and `last_90_days`
        end today and include it; `last_12_months` starts the day after today
        minus twelve months. `next_month`, `next_quarter` and `next_year` cover
        the whole next calendar month, quarter or year.
      enum:
        - this_month
        - last_month
        - this_quarter
        - last_quarter
        - this_year
        - last_year
        - month_to_date
        - quarter_to_date
        - year_to_date
        - last_30_days
        - last_90_days
        - last_12_months
        - next_month
        - next_quarter
        - next_year
    Interval:
      type: string
      description: A period bucket for report rows.
      enum:
        - day
        - week
        - month
      default: month
    Currency:
      type: string
      description: ISO 4217 alphabetic currency code.
      pattern: ^[A-Z]{3}$
      example: RON
    Direction:
      type: string
      description: >-
        Whether money comes in or goes out. On a transaction or forecast it
        follows the sign of `amount`.
      enum:
        - inflow
        - outflow
    Activity:
      type: string
      description: Cash flow statement section the category belongs to.
      enum:
        - operating
        - investing
        - financing
    ResolvedPeriod:
      type: object
      description: The window actually computed.
      required:
        - from
        - to
        - macro
        - interval
      properties:
        from:
          type: string
          format: date
        to:
          type: string
          format: date
        macro:
          oneOf:
            - $ref: '#/components/schemas/PeriodMacro'
            - type: 'null'
          description: >-
            The macro that produced these dates, or `null` when they were given
            directly.
        interval:
          $ref: '#/components/schemas/Interval'
    Conversion:
      type: object
      description: What was done to make amounts comparable.
      required:
        - applied
        - currency
        - basis
      properties:
        applied:
          type: boolean
          description: '`false` when every amount was already in `currency`.'
        currency:
          $ref: '#/components/schemas/Currency'
        basis:
          type: string
          description: >-
            `transaction_date` converts each movement at the rate for its own
            date. `balance_date` converts a whole balance at one rate. `none`
            when nothing was converted.
          enum:
            - transaction_date
            - balance_date
            - none
    CashFlowSummaryTotals:
      type: object
      description: >-
        The whole window added up, over the same transactions and forecasts as
        the rows.
      required:
        - currency
        - actual_inflow
        - actual_outflow
        - actual_count
        - forecast_inflow
        - forecast_outflow
        - forecast_count
        - inflow
        - outflow
        - net
        - overdue_inflow
        - overdue_outflow
        - starting_balance
        - opened_accounts
        - transfers
        - excluded
        - final_balance
      properties:
        currency:
          $ref: '#/components/schemas/Currency'
        actual_inflow:
          $ref: '#/components/schemas/Money'
        actual_outflow:
          $ref: '#/components/schemas/Money'
        actual_count:
          type: integer
        forecast_inflow:
          $ref: '#/components/schemas/Money'
        forecast_outflow:
          $ref: '#/components/schemas/Money'
        forecast_count:
          type: integer
        inflow:
          $ref: '#/components/schemas/Money'
        outflow:
          $ref: '#/components/schemas/Money'
        net:
          $ref: '#/components/schemas/Money'
        overdue_inflow:
          $ref: '#/components/schemas/Money'
          description: >-
            Remaining amount of the overdue unrealised inflow forecasts matching
            the filters that no row counted. Every one of them when
            `include_overdue` is off, those dated outside the window when it is
            on.
        overdue_outflow:
          $ref: '#/components/schemas/Money'
          description: The same for outflow forecasts, negative.
        starting_balance:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            The first period's `starting_balance`. `null` when `group_by` or
            `direction` is given.
        opened_accounts:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            The periods' figures added up over the window. `null` when
            `group_by` or `direction` is given.
        transfers:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            The periods' figures added up over the window. `null` when
            `group_by` or `direction` is given.
        excluded:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            The periods' figures added up over the window. `null` when
            `group_by` or `direction` is given.
        final_balance:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            The last period's `final_balance`. `null` when `group_by` or
            `direction` is given.
    CashFlowSummaryRow:
      type: object
      required:
        - period_start
        - period_end
        - group
        - currency
        - actual_inflow
        - actual_outflow
        - actual_count
        - forecast_inflow
        - forecast_outflow
        - forecast_count
        - inflow
        - outflow
        - net
        - starting_balance
        - opened_accounts
        - transfers
        - excluded
        - final_balance
      properties:
        period_start:
          type: string
          format: date
        period_end:
          type: string
          format: date
        group:
          oneOf:
            - $ref: '#/components/schemas/ReportGroup'
            - type: 'null'
        currency:
          $ref: '#/components/schemas/Currency'
        actual_inflow:
          $ref: '#/components/schemas/Money'
          description: >-
            Transactions coming in during the period, after the report's
            exclusions.
        actual_outflow:
          $ref: '#/components/schemas/Money'
          description: >-
            Transactions going out during the period, after the report's
            exclusions. Negative.
        actual_count:
          type: integer
          description: Transactions behind this row, after the report's exclusions.
        forecast_inflow:
          $ref: '#/components/schemas/Money'
          description: >-
            Remaining amount of the unrealised inflow forecasts dated in the
            period.
        forecast_outflow:
          $ref: '#/components/schemas/Money'
          description: >-
            Remaining amount of the unrealised outflow forecasts dated in the
            period. Negative.
        forecast_count:
          type: integer
          description: Forecasts behind this row.
        inflow:
          $ref: '#/components/schemas/Money'
          description: >-
            `actual_inflow` plus `forecast_inflow`. What the cash flow screen
            shows.
        outflow:
          $ref: '#/components/schemas/Money'
          description: >-
            `actual_outflow` plus `forecast_outflow`. What the cash flow screen
            shows.
        net:
          $ref: '#/components/schemas/Money'
          description: '`inflow` plus `outflow`. What the cash flow screen shows.'
        starting_balance:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            Balance of the workspace's accounts at the start of the period,
            projected when the period starts after today. `null` when `group_by`
            or `direction` is given.
        opened_accounts:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            The opening balances of accounts opened in the period. Not part of
            the flows. `null` when `group_by` or `direction` is given.
        transfers:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            Net of transfers between the workspace's own accounts in the period.
            Not part of the flows. `null` when `group_by` or `direction` is
            given.
        excluded:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            Net of movements the user excluded from cash flow in the period. Not
            part of the flows. `null` when `group_by` or `direction` is given.
        final_balance:
          oneOf:
            - $ref: '#/components/schemas/Money'
            - type: 'null'
          description: >-
            Balance at the end of the period, projected when the period ends
            after today. Starting balance plus `net`, `opened_accounts`,
            `transfers` and `excluded`. `null` when `group_by` or `direction` is
            given.
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - code
            - message
            - param
            - request_id
          properties:
            type:
              type: string
              enum:
                - invalid_request
                - authentication
                - not_found
                - rate_limit
                - server
            code:
              type: string
              description: >
                Stable machine-readable reason. Branch on this, not on
                `message`. One of

                `invalid_parameter`, `invalid_cursor`, `limit_out_of_range`,
                `invalid_expand`,

                `as_of_in_future`, `unauthorized`, `forbidden`,
                `resource_not_found`,

                `too_many_groups`, `period_too_long`, `rate_limited`,
                `internal_error`.
            message:
              type: string
              description: Human-readable explanation. Wording may change.
            param:
              type:
                - string
                - 'null'
              description: The query parameter at fault, when there is one.
            request_id:
              type: string
              description: Quote this when contacting support.
    Money:
      type: string
      description: >-
        Decimal amount as a string with two decimals. Negative means an outflow
        on transactions, forecasts and report figures.
      pattern: ^-?[0-9]+\.[0-9]{2}$
      example: '-1250.00'
    ReportGroup:
      type: object
      description: What a report row is grouped by. `null` on rows grouped by period alone.
      required:
        - dimension
        - id
        - label
      properties:
        dimension:
          type: string
          example: category
        id:
          type:
            - string
            - 'null'
          format: uuid
          description: >-
            The grouped object's id, the activity's for `activity`. `null` for
            `direction` and `status`, and for the `none` and `other` rows.
        label:
          type: string
          description: >-
            Name of the group. Non-object groups are lowercase codes on every
            summary: `inflow` or `outflow`, an activity code such as
            `operating`, a forecast status such as `planned`, and `none` or
            `other`.
          example: Telecom
  responses:
    BadRequest:
      description: A parameter is invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: invalid_request
              code: invalid_parameter
              message: direction must be 'inflow' or 'outflow'
              param: direction
              request_id: 0HNF8K3QJL2VM:00000001
    Unauthorized:
      description: The API key is missing, malformed, unknown or revoked.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: authentication
              code: unauthorized
              message: Missing, malformed, unknown or revoked API key
              param: null
              request_id: 0HNF8K3QJL2VM:00000001
    Forbidden:
      description: >-
        The key is valid but the company's ThinkOut plan does not include the
        API.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: authentication
              code: forbidden
              message: >-
                The API is not included in this company's ThinkOut plan. Contact
                support@thinkout.io to enable it.
              param: null
              request_id: 0HNF8K3QJL2VM:00000001
    RequestTooLarge:
      description: >
        The report would exceed 1000 rows. `period_too_long` is raised from the
        window and

        interval alone, `too_many_groups` after grouping. Narrow the window,
        coarsen the

        interval or add filters.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: invalid_request
              code: too_many_groups
              message: >-
                Grouping by counterparty over this period produces 1240 groups.
                The maximum is 1000. Narrow the period or the filters.
              param: group_by
              request_id: 0HNF8K3QJL2VM:00000001
    RateLimited:
      description: >-
        More than 120 requests in the current minute for this key. Wait for the
        seconds in `Retry-After`.
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds until the minute window resets.
        X-RateLimit-Limit:
          schema:
            type: integer
          description: Requests allowed per minute.
        X-RateLimit-Remaining:
          schema:
            type: integer
          description: Requests left in the current minute.
        X-RateLimit-Reset:
          schema:
            type: integer
          description: Seconds until the minute window resets.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              type: rate_limit
              code: rate_limited
              message: Too many requests
              param: null
              request_id: 0HNF8K3QJL2VM:00000001
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        A workspace API key created in ThinkOut settings. One key reads one
        workspace.

````

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