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

# Create a bank connection

> Required scope: `bank:write`.

Growth plan. Switched on per workspace by Sahl: until then a key cannot be issued with this scope and calls answer `403` `bank_scope_not_allowed`. No bank data provider is live: data is a sandbox simulation (send `X-Sahl-Environment: sandbox`), and in production create, refresh, transactions and analysis answer `409` `bank_connect_unavailable`.

Sandbox only today: files a simulated, already connected account. In production this answers `409` `bank_connect_unavailable`.

Guide: [Bank connections and open banking](/guides/open-banking).



## OpenAPI

````yaml /openapi.json post /v1/partner/bank-connections
openapi: 3.1.0
info:
  title: Sahl Partner API
  version: 0.2.0
  description: >-
    Server-to-server API for lenders and banks: document reading, verification,
    risk assessment and eID checks. Authenticate with `Authorization: Bearer
    <API key>`. Paths are relative to the server URL. New workspaces start in
    sandbox.
servers:
  - url: https://app.sahlfinancial.com/api
    description: Single API host. Send environment=sandbox (the default) for test data.
security:
  - bearerAuth: []
tags:
  - name: KYC
    description: Read documents, verify a profile, assess risk, start an eID check.
  - name: Bank connections (Growth)
    description: >-
      Growth plan, switched on per workspace by Sahl. Sandbox simulation today;
      production answers 409 until a bank data provider is live.
paths:
  /v1/partner/bank-connections:
    post:
      tags:
        - Bank connections (Growth)
      summary: Create a bank connection
      description: >-
        Required scope: `bank:write`.


        Growth plan. Switched on per workspace by Sahl: until then a key cannot
        be issued with this scope and calls answer `403`
        `bank_scope_not_allowed`. No bank data provider is live: data is a
        sandbox simulation (send `X-Sahl-Environment: sandbox`), and in
        production create, refresh, transactions and analysis answer `409`
        `bank_connect_unavailable`.


        Sandbox only today: files a simulated, already connected account. In
        production this answers `409` `bank_connect_unavailable`.


        Guide: [Bank connections and open banking](/guides/open-banking).
      operationId: partner_bank_post
      parameters:
        - 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
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BankConnectionCreate'
            example:
              bank_code: attijariwafa
              bank_name: Attijariwafa bank
              case_id: 7e3b9a14-2d6c-4c85-b1f0-6a8d4e2c9b37
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankConnectionResponse'
              example:
                id: c1a4e2d7-93b5-4f08-8a6d-2e7b1f9c3d54
                tenant_id: 0b6f5a3e-7c1d-4e0a-9d2f-3a1c5e8b7f10
                case_id: 7e3b9a14-2d6c-4c85-b1f0-6a8d4e2c9b37
                bank_code: attijariwafa
                bank_name: Attijariwafa bank
                account_holder: Test Client
                account_last4: '4821'
                status: connected
                link_token: Zk3x...redacted
                connected_at: '2026-10-07T09:14:22Z'
                expires_at: '2027-01-05T09:14:22Z'
                avg_balance: 21450
                monthly_income: 18200
                monthly_expenses: 11800
                transaction_count: 96
                cash_flow_data: null
                environment: sandbox
                created_at: '2026-10-07T09:14:22Z'
                updated_at: '2026-10-07T09:14:22Z'
        '401':
          description: Missing, invalid, revoked or expired API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            The key lacks the scope (`insufficient_scope`), or the workspace is
            not enabled for the partner bank API (`bank_scope_not_allowed`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                detail:
                  code: bank_scope_not_allowed
                  message: This workspace is not enabled for the partner bank API.
        '409':
          description: >-
            Production, or no Sandbox environment named: 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:
    BankConnectionCreate:
      properties:
        bank_code:
          type: string
          maxLength: 50
        bank_name:
          type: string
          maxLength: 100
        case_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
      type: object
      required:
        - bank_code
        - bank_name
    BankConnectionResponse:
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        case_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
        bank_code:
          type: string
        bank_name:
          type: string
        account_holder:
          anyOf:
            - type: string
            - type: 'null'
        account_last4:
          anyOf:
            - type: string
            - type: 'null'
        status:
          type: string
        link_token:
          anyOf:
            - type: string
            - type: 'null'
        connected_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
        expires_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
        avg_balance:
          anyOf:
            - type: number
            - type: 'null'
        monthly_income:
          anyOf:
            - type: number
            - type: 'null'
        monthly_expenses:
          anyOf:
            - type: number
            - type: 'null'
        transaction_count:
          type: integer
        cash_flow_data:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
        environment:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      type: object
      required:
        - id
        - tenant_id
        - case_id
        - bank_code
        - bank_name
        - account_holder
        - account_last4
        - status
        - link_token
        - connected_at
        - expires_at
        - avg_balance
        - monthly_income
        - monthly_expenses
        - transaction_count
        - cash_flow_data
        - environment
        - created_at
        - updated_at
    Error:
      type: object
      title: Error
      description: >-
        FastAPI error body. `detail` is a string, or an object with `code` and
        `message` (extra keys possible).
      properties:
        detail:
          oneOf:
            - type: string
            - 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
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key created in the console. Scopes: kyc:extract, kyc:verify,
        kyc:eid; bank:read, bank:write (Growth plan, enabled per workspace by
        Sahl).

````

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