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

# Get the cash-flow analysis of a bank connection

> **Who can call it:** Any signed-in member of the workspace.

Income regularity, risk flags, savings rate and debt-to-income, generated from the connection id.

**Production behaviour.** No open-banking provider is live. This route answers `409` with the code `bank_connect_unavailable` unless the request is made in the Sandbox: send `X-Sahl-Environment: sandbox` (or `?environment=sandbox`). In the Sandbox the data is simulated and derived from the connection id; it is not read from a bank. A request with no environment is also refused.

**Auth:** dashboard session (`Authorization: Bearer <access token>`). Not available with a partner API key.



## OpenAPI

````yaml /openapi-console.json get /v1/bank-connections/{connection_id}/analysis
openapi: 3.1.0
info:
  title: Sahl Console API
  version: 0.1.0
  description: >-
    **Used by the Sahl console. Not available with partner API keys. Contact
    Sahl if you need programmatic access.**


    These are the routes the Sahl console calls with a signed-in user's session.
    They are documented so that a developer or a workspace admin can see what
    the console does, with the real request and response models. They are
    **not** part of the [Partner API](/api-reference/introduction): an API key
    is refused here (401), there is no try-it, and the shapes can change with
    the console.


    Authentication: `Authorization: Bearer <access token>`, the JWT the console
    gets from `POST /v1/auth/login` (30 minutes; renewed with `POST
    /v1/auth/refresh`, refresh token valid 7 days). There is no cookie. The role
    of the user is read from the user's record on every call, not from the
    token. Every call is scoped to the workspace of the user.


    Common answers: 401 (no or bad session), 403 `Insufficient permissions`
    (role), 422 (validation), 429 (100 requests per minute and IP). Error bodies
    have the same three shapes as the Partner API: see [Errors](/errors).
servers:
  - url: https://app.sahlfinancial.com/api
    description: Console host. Same host as the Partner API.
security:
  - dashboardSession: []
tags:
  - name: Bank connections
    description: Simulated in the Sandbox; 409 `bank_connect_unavailable` elsewhere.
  - name: Cases
    description: Client files that group documents, a score and a decision.
  - name: Documents
    description: Upload, status, result and download.
  - name: Webhooks
    description: Manage the endpoints that receive events.
  - name: API keys
    description: Create, rotate and revoke the keys used with the Partner API.
  - name: Scoring policies
    description: Weights and thresholds of the credit score.
  - name: Flows
    description: Verification flows (graphs) and their simulation.
paths:
  /v1/bank-connections/{connection_id}/analysis:
    get:
      tags:
        - Bank connections
      summary: Get the cash-flow analysis of a bank connection
      description: >-
        **Who can call it:** Any signed-in member of the workspace.


        Income regularity, risk flags, savings rate and debt-to-income,
        generated from the connection id.


        **Production behaviour.** No open-banking provider is live. This route
        answers `409` with the code `bank_connect_unavailable` unless the
        request is made in the Sandbox: send `X-Sahl-Environment: sandbox` (or
        `?environment=sandbox`). In the Sandbox the data is simulated and
        derived from the connection id; it is not read from a bank. A request
        with no environment is also refused.


        **Auth:** dashboard session (`Authorization: Bearer <access token>`).
        Not available with a partner API key.
      operationId: getBankConnectionAnalysis
      parameters:
        - name: connection_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
            title: Connection Id
        - name: environment
          in: query
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: Environment
        - name: X-Sahl-Environment
          in: header
          required: false
          schema:
            anyOf:
              - type: string
              - type: 'null'
            title: X-Sahl-Environment
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAnalysisResponse'
              example:
                income_regularity:
                  score: 0.93
                  pattern: monthly_25th
                  employer: OCP GROUP
                  day_of_month: 25
                  consecutive_months: 9
                  risk: low
                risk_flags:
                  overdrafts: 0
                  bounced_checks: 0
                  gambling_transactions: 0
                  large_cash_withdrawals: 1
                  debt_payments_detected: 2
                  flagged_items:
                    - Large cash withdrawal of 5000 MAD on 14/02
                savings_rate: 0.35
                estimated_dti: 0.31
                avg_end_of_month_balance: 9000
                avg_balance: 21000
                monthly_income: 18000
                monthly_expenses: 11700
        '401':
          description: No session, expired token, ended session or inactive account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                detail: Invalid or expired token
        '403':
          description: >-
            The role is not allowed, MFA enrolment is pending, or the
            environment is refused.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                detail: Insufficient permissions
        '404':
          description: Unknown connection.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                detail: Bank connection not found
        '409':
          description: >-
            `bank_connect_unavailable`: not a Sandbox request, so no simulated
            data. No bank data provider is live.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                detail:
                  code: bank_connect_unavailable
                  message: >-
                    Bank connection is not available yet. No bank data provider
                    is live for this workspace.
        '422':
          description: Validation error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                detail:
                  - type: missing
                    loc:
                      - body
                      - bank_code
                    msg: Field required
                    input: {}
        '429':
          description: >-
            More than 100 requests per minute from one IP address. The body has
            no `detail`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
              example:
                code: rate_limit_exceeded
                message: Too many requests. Please slow down.
          headers:
            Retry-After:
              schema:
                type: integer
              description: Seconds to wait.
components:
  schemas:
    BankAnalysisResponse:
      properties:
        income_regularity:
          $ref: '#/components/schemas/IncomeRegularity'
        risk_flags:
          $ref: '#/components/schemas/RiskFlags'
        savings_rate:
          type: number
        estimated_dti:
          type: number
        avg_end_of_month_balance:
          type: number
        avg_balance:
          type: number
        monthly_income:
          type: number
        monthly_expenses:
          type: number
      type: object
      required:
        - income_regularity
        - risk_flags
        - savings_rate
        - estimated_dti
        - avg_end_of_month_balance
        - avg_balance
        - monthly_income
        - monthly_expenses
    Error:
      type: object
      description: >-
        FastAPI error body. `detail` is a string, a list (422), or an object
        with `code` and `message` (extra keys possible).
      properties:
        detail:
          oneOf:
            - type: string
            - items:
                additionalProperties: true
                type: object
              type: array
            - type: object
              additionalProperties: true
              properties:
                code:
                  type: string
                message:
                  type: string
      required:
        - detail
    RateLimitError:
      type: object
      description: Top-level `code` and `message`, no `detail`.
      properties:
        code:
          type: string
        message:
          type: string
      required:
        - code
        - message
    IncomeRegularity:
      properties:
        score:
          type: number
        pattern:
          type: string
        employer:
          type: string
        day_of_month:
          type: integer
        consecutive_months:
          type: integer
        risk:
          type: string
      type: object
      required:
        - score
        - pattern
        - employer
        - day_of_month
        - consecutive_months
        - risk
    RiskFlags:
      properties:
        overdrafts:
          type: integer
        bounced_checks:
          type: integer
        gambling_transactions:
          type: integer
        large_cash_withdrawals:
          type: integer
        debt_payments_detected:
          type: integer
        flagged_items:
          items:
            type: string
          type: array
      type: object
      required:
        - overdrafts
        - bounced_checks
        - gambling_transactions
        - large_cash_withdrawals
        - debt_payments_detected
        - flagged_items
  securitySchemes:
    dashboardSession:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        The access token (JWT) of a signed-in console user, from `POST
        /v1/auth/login`. It lasts 30 minutes. It is not an API key: a partner
        API key is refused here. There is no cookie.

````

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