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

# Move the paying account's Nordea Business connection forward

> Open Payments reaches a Nordea Business account only after the company has applied for Corporate Access Lite inside Nordea Business and Nordea has activated it. A signed-in company admin declares the application (`application_submitted`). A company admin or LAC staff asks Open Payments about the paying account now (`observe`): the provider lists the company's accounts with their statement-enrichment time, LAC records the observation, and current evidence about the current paying account (listed, enabled, a statement enrichment dated after the declaration and at most 14 days old) activates the connection with a machine-verifiable evidence reference; evidence from before the current declaration never activates, so a reset connection cannot re-activate from old statements; LAC also runs this read once a day on a settings read while the application is pending. A signed-in LAC staff member, under the staff customer-write confirmation headers, may record Nordea's activation from the customer's forwarded activation letter (`active`): the letter is one of the customer's retained uploads (`evidence_document_id` with its `evidence_sha256`, a PDF or an image under an approved archive prefix), `letter_account_iban` is the payment account it names and must be the paying account, and `agreement_id` is the bank's agreement identifier printed on it. The recorded evidence names the document and its digest; a typed note (`evidence_ref`) is refused. The same record is reachable for agents as the operation `payments.bank_connection.activate@1`. Only an active connection lets the database derive `delivery_enabled`; every release still proves live provider readiness. `expected_row_version` pins the paying account version the caller saw. A changed paying IBAN returns the connection to `not_started`.



## OpenAPI

````yaml /openapi.yaml post /payment-settings/bank-connection
openapi: 3.1.0
info:
  title: LAC Customer API
  version: 2026-10-06.2
  description: >
    Last Accounting Company (LAC) is an AI-native accounting firm for Finnish
    SMBs:

    continuous reconciliation, daily close, real-time dashboards, and full Vero
    reporting.

    This API is the same surface the LAC customer portal UI uses. It gives you
    programmatic

    access to your books (read-only general-ledger views), financial statements,
    documents,

    invoicing, payroll, source-system connections, and the message channel to
    Björn, the

    accounting agent.


    ## Authentication


    Customer API requests carry `Authorization: Bearer <token>`. Two token kinds
    are accepted:


    - **Portal API key** (`lac_sk_...`) — minted in portal Settings → API
    access. Keys have a
      scope of `read` or `write`. Read-scoped keys are refused on all mutating methods
      (POST/PATCH/DELETE). Write-scoped keys act as the `operator` role: they can never
      use payroll endpoints (reads included), change company settings, grant access,
      approve or return an invoice, or manage API keys. Payroll and company settings
      require an interactive admin or existing broad approver. Invoice decisions require the matching invoice
      review permission. Write-scoped keys can prepare draft partner
      seller profiles. An interactive company admin must review the evidence and activate
      a profile or change an active profile.
    - **Firebase ID token** — the interactive session token used by the portal
    UI itself.


    The Shopify App endpoints are provider-facing exceptions with explicit

    per-operation security: App Home assets are public, App Bridge actions use

    a Shopify session JWT, and privacy webhooks use Shopify's raw-body HMAC.


    API keys are pinned to a single company, so the `customer_id` parameter
    (query string on

    GETs, body field on writes) can always be omitted when authenticating with
    an API key.

    Interactive tokens with access to multiple companies use `customer_id` to
    select one.


    ## Conventions


    - All field names are `snake_case` on the wire.

    - Monetary amounts are **integer cents** (fields suffixed `_cents`).

    - Rates and percentages are **basis points** (fields suffixed
    `_basis_points`;
      10000 = 100%, e.g. Finnish standard VAT 25.5% = 2550).
    - Quantities on invoice lines are decimal strings (e.g. `"1"`, `"2.5"`).

    - Dates are `YYYY-MM-DD`; periods are `YYYY-MM`; ranges accept `YYYY-MM`,
    `YYYY-Qn`,
      `YYYY`, `all`, `this_month`, or `last_6_months`.

    ## Limits


    - Document uploads: at most 20 files and 25 MB per request.

    - Sheet pagination: `limit` is capped at 200 rows per page (0 =
    unpaginated).


    ## Errors


    Errors return a JSON envelope `{"error": "...", "detail": "..."}` with a
    conventional

    HTTP status code (401 missing/invalid token, 403 insufficient scope or role,
    404 not

    found, 422 validation failure).


    More at
    [docs.lastaccountingcompany.com](https://docs.lastaccountingcompany.com).
  contact:
    name: Last Accounting Company
    url: https://docs.lastaccountingcompany.com
servers:
  - url: https://api.app.lastaccountingcompany.com/portal
    description: Production (note the /portal base path).
security:
  - apiKey: []
tags:
  - name: Company
    description: Company profile, identity, overview, and agent status.
  - name: Onboarding
    description: Saved customer onboarding facts, source inventory, and opening statements.
  - name: Books
    description: >-
      Read-only windows into the canonical general ledger: the spreadsheet-style
      Books/VAT sheet, financial statements, and analytics. There is no
      cell-edit or batch-edit API — the books are maintained by LAC. The one
      write here is a row declaration: your answer about a row (no receipt
      exists, private, a split, or a different booking), recorded as evidence
      for Björn.
  - name: Dimensions
    description: >-
      Project, cost-centre, department, and customer-defined reporting lenses
      over posted general-ledger lines. Provider catalogs are read-only; local
      axes and values are available for bank/file-only books.
  - name: Documents
    description: Receipt/invoice/contract uploads and per-file ingest metadata.
  - name: Messages
    description: The chat channel to Björn, the accounting agent.
  - name: Work log
    description: >-
      Append-only work-hours log (date, minutes, note). Hours are records for
      invoicing and payroll evidence; they do not post to the books. Kilometres
      are not logged here — vehicle travel is submitted as an expense claim in
      the portal, where statutory reimbursement rates apply.
  - name: Filings
    description: Filing authorization, review requests, and produced output packages.
  - name: Invoicing
    description: >-
      Sales invoicing — drafts, partner seller profiles, e-invoice sending, PDF
      finalizing, credit notes, reminders, recurring templates, and the
      invoice-customer register. LAC sends buyer invoices on the e-invoice
      network only. A partner-profile invoice also sends its legal seller a
      bookkeeping PDF copy.
  - name: Payroll
    description: >-
      Payroll workspace — employees, tax cards, employer settings, draft runs,
      and payslips. Every payroll operation (reads included) requires an
      interactive admin or existing broad-approver session and is NOT available
      to API keys.
  - name: Payments
    description: >-
      Review and named-human release for source-bound purchase, payroll, and
      reimbursement payments. Direct Open Payments delivery is the only rail:
      there is no manual payment composer and no bank or Wise file. A batch that
      cannot be delivered directly to the bank fails closed rather than becoming
      the customer's manual task.
  - name: Connections
    description: >-
      Source-system connections (bank, settlement providers, commerce,
      accounting systems, inbox/Gmail, Google Sheets) and service-connection
      requests/confirmations. PayPal connects with the company's own PayPal app,
      whose Client ID and Secret this API accepts, or with PayPal partner
      consent, which depends on PayPal approving LAC as a partner and returns a
      URL that a company admin must open. Other browser-interactive consent
      flows remain portal-only.
  - name: Shopify App
    description: >-
      Public Shopify App Home, App Bridge token exchange, installation handoff,
      and mandatory privacy webhooks. Offline access tokens never enter a
      browser.
  - name: Imports
    description: Historical import runs (e.g. migrated books) and their artifacts.
  - name: API keys
    description: >-
      Manage portal API keys. These endpoints require an interactive admin
      session (Firebase token) and are NOT available to API-key bearers, which
      receive 403.
  - name: Lens
    description: >-
      Typed, display-ready read models over the books: the transactions window
      (full row universe, three-state status, keyset pagination), the per-row
      booking view, data coverage, and the connections catalog.
  - name: Accounting
    description: >-
      The accountant's read models: general ledger, journal entries, context
      cards, the filings strip with previews, and the SQL explorer. Every
      endpoint here requires LAC staff access or the company admin role; other
      bearers receive 403.
paths:
  /payment-settings/bank-connection:
    post:
      tags:
        - Payments
      summary: Move the paying account's Nordea Business connection forward
      description: >-
        Open Payments reaches a Nordea Business account only after the company
        has applied for Corporate Access Lite inside Nordea Business and Nordea
        has activated it. A signed-in company admin declares the application
        (`application_submitted`). A company admin or LAC staff asks Open
        Payments about the paying account now (`observe`): the provider lists
        the company's accounts with their statement-enrichment time, LAC records
        the observation, and current evidence about the current paying account
        (listed, enabled, a statement enrichment dated after the declaration and
        at most 14 days old) activates the connection with a machine-verifiable
        evidence reference; evidence from before the current declaration never
        activates, so a reset connection cannot re-activate from old statements;
        LAC also runs this read once a day on a settings read while the
        application is pending. A signed-in LAC staff member, under the staff
        customer-write confirmation headers, may record Nordea's activation from
        the customer's forwarded activation letter (`active`): the letter is one
        of the customer's retained uploads (`evidence_document_id` with its
        `evidence_sha256`, a PDF or an image under an approved archive prefix),
        `letter_account_iban` is the payment account it names and must be the
        paying account, and `agreement_id` is the bank's agreement identifier
        printed on it. The recorded evidence names the document and its digest;
        a typed note (`evidence_ref`) is refused. The same record is reachable
        for agents as the operation `payments.bank_connection.activate@1`. Only
        an active connection lets the database derive `delivery_enabled`; every
        release still proves live provider readiness. `expected_row_version`
        pins the paying account version the caller saw. A changed paying IBAN
        returns the connection to `not_started`.
      operationId: updatePaymentBankConnection
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - customer_id
                - expected_row_version
                - state
              properties:
                customer_id:
                  type: string
                expected_row_version:
                  type: integer
                  format: int64
                  minimum: 1
                state:
                  type: string
                  enum:
                    - application_submitted
                    - observe
                    - active
                evidence_ref:
                  type: string
                  maxLength: 500
                  deprecated: true
                  description: Retired free-text note; refused for `active`.
                evidence_document_id:
                  type: string
                  maxLength: 128
                  description: >-
                    Required for `active`. The customer's retained activation
                    letter (an evidence.document of this tenant, PDF or image).
                evidence_sha256:
                  type: string
                  pattern: ^[0-9a-f]{64}$
                  description: >-
                    Required for `active`. The digest of the letter as the
                    uploads list shows it; the server activates exactly those
                    retained bytes or answers 409.
                letter_account_iban:
                  type: string
                  description: >-
                    Required for `active`. The payment account the letter names;
                    must be the current paying account.
                agreement_id:
                  type: string
                  maxLength: 64
                  description: >-
                    The bank's agreement identifier printed on the letter
                    (Nordea "Sopimustunnus").
      responses:
        '200':
          description: Current payment settings.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentSettings'
        '400':
          description: >-
            Unknown state, an activation without the letter or with a letter for
            another account, a document that is not a readable upload, or a
            check before the application was declared.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Not a company admin, or a customer recording the activation.
        '409':
          description: >-
            The paying account changed; the transition was already recorded; the
            paying bank's route has no bank-side agreement to declare, check or
            activate (it authorises at the first payment); account checks are
            not enabled for this deployment; another check of this connection is
            still running on another portal instance; or the sign-in carries no
            derivable provider identity.
        '428':
          description: Staff customer-write confirmation missing.
        '502':
          description: >-
            Open Payments could not be read; the recorded connection state is
            unchanged.
      security:
        - firebaseToken: []
components:
  schemas:
    PaymentSettings:
      type: object
      additionalProperties: false
      required:
        - banks
        - can_change
        - can_verify
        - terms
        - verification
      properties:
        can_change:
          type: boolean
        can_verify:
          type: boolean
        setup:
          type: object
          additionalProperties: false
          required:
            - iban
            - bic
            - bank_name
            - delivery
            - bank_route_readiness
            - row_version
            - can_change
            - bank_connection
          properties:
            iban:
              type: string
            bic:
              type: string
            bank_name:
              type: string
            delivery:
              type: string
              enum:
                - unavailable
                - direct
            bank_route:
              type: string
              enum:
                - iso_corporate
                - psd2_pis
              description: >-
                The route LAC operates for the saved bank; absent when the bank
                has no route policy.
            bank_route_readiness:
              type: string
              enum:
                - live
                - provider_listed
                - not_offered
              description: >-
                Whether LAC has proven the saved bank's route. Only `live` can
                ever derive direct delivery; `provider_listed` keeps the account
                and the customer-side steps but releases nothing; `not_offered`
                means no route policy exists for the bank.
            bank_route_guide:
              type: string
              description: The setup guidance the portal renders for the saved bank.
            row_version:
              type: integer
              format: int64
            can_change:
              type: boolean
            bank_connection:
              description: >-
                The Nordea Business side of the paying account. `can_submit`:
                the signed-in company admin may declare the Corporate Access
                Lite application. `can_check`: the signed-in company admin or
                LAC staff may ask Open Payments about the account now.
                `can_activate`: signed-in LAC staff may record Nordea's
                activation as break-glass evidence. `last_checked_at` is the
                latest provider read about this paying account and
                `provider_enriched_at` the statement-enrichment time it
                reported, present only once Nordea delivers statements.
              type: object
              additionalProperties: false
              required:
                - state
                - can_submit
                - can_activate
                - can_check
                - checks_enabled
              properties:
                state:
                  $ref: '#/components/schemas/PaymentBankConnectionState'
                submitted_at:
                  type: string
                  format: date-time
                activated_at:
                  type: string
                  format: date-time
                last_checked_at:
                  type: string
                  format: date-time
                provider_enriched_at:
                  type: string
                  format: date-time
                can_submit:
                  type: boolean
                can_activate:
                  type: boolean
                can_check:
                  type: boolean
                checks_enabled:
                  type: boolean
                  description: >-
                    LAC's provider account reads are enabled for this
                    deployment. Until the provider contract is confirmed they
                    stay off: nothing is checked on a settings read or on
                    request, and the customer forwards Nordea's activation
                    message instead.
        banks:
          description: >-
            The banks a company admin may choose as the paying bank: the
            provider lists them for the market and LAC has a route policy for
            them. `route` is how a payment reaches the bank (`iso_corporate`: a
            bank-side corporate agreement and the customer confirms the uploaded
            file in the bank; `psd2_pis`: payment initiation the customer
            authorises at release). `readiness` is `live` when LAC has proven
            the route end to end and releases money on it, `provider_listed`
            when the provider lists the bank but LAC has not verified the route
            yet: the account can be saved and the customer-side steps started,
            but nothing is released. `activation` names what marks the bank
            connection active and `guide` the setup guidance the portal renders
            for the bank. Live routes sort first.
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - bic
              - name
              - route
              - readiness
              - activation
              - guide
            properties:
              bic:
                type: string
              name:
                type: string
              route:
                type: string
                enum:
                  - iso_corporate
                  - psd2_pis
              readiness:
                type: string
                enum:
                  - live
                  - provider_listed
              activation:
                type: string
                enum:
                  - bank_letter_or_provider_read
                  - psd2_consent
              guide:
                type: string
        terms:
          type: object
          additionalProperties: false
          required:
            - version
            - url
            - accepted
          properties:
            version:
              type: string
            url:
              type: string
              format: uri-reference
            accepted:
              type: boolean
        verification:
          description: >-
            Authoritative KYC UI state derived from LAC's hosted-flow attempt
            record and the provider's live status. `started` means LAC returned
            a hosted URL that remains the one actionable flow for 24 hours;
            `retry` means that URL expired or Open Payments answered Invalid;
            `pending` means a start has no recorded outcome and must not be
            repeated before the same 24-hour boundary. Only `clear` represents
            current provider validity.
          oneOf:
            - type: object
              additionalProperties: false
              required:
                - state
              properties:
                state:
                  type: string
                  enum:
                    - clear
                    - pending
                    - required
            - type: object
              additionalProperties: false
              required:
                - state
                - started_at
              properties:
                state:
                  type: string
                  enum:
                    - started
                    - unconfirmed
                    - retry
                started_at:
                  type: string
                  format: date-time
    PaymentBankConnectionState:
      type: string
      enum:
        - not_started
        - application_submitted
        - active
    Error:
      type: object
      description: Standard error envelope.
      properties:
        error:
          type: string
          description: Machine-readable error message.
        detail:
          type: string
          description: Human-readable detail.
  responses:
    Unauthorized:
      description: Missing or invalid bearer token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: lac_sk_...
      description: >-
        Portal API key minted in portal Settings → API access. Scope `read` or
        `write`; pinned to one company. Send as `Authorization: Bearer
        lac_sk_...`.
    firebaseToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Firebase ID token from an interactive portal session. Required for
        interactive operations (payroll, company settings, API-key management)
        and invoice decisions allowed by the member's review permissions.

````

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