SimpleFIN version 2 was released on 19 March 2026. It does not turn the protocol into a sprawling banking platform; it improves names, error handling and selective reads.
Changes that affect application code
The parent concept is now Connection rather than Organization, reflecting a provider-side connection containing accounts and health information. Version 2 replaces the older errors field with structured errlist, making it possible to classify and present problems without scraping prose.
Two query features can reduce transfer: balances-only=1 for lightweight balance reads and account= for selected accounts. These are operational improvements, not promises of faster upstream bank refreshes.

Normalize the wire contract
Do not let JSON object names dictate your persistence schema. Add an adapter that converts both Organization and Connection into one internal model. Record the provider and requested protocol version in connection diagnostics so support can separate a parser problem from a provider-freshness problem.
Start with fixtures, not the scheduler. Freeze synthetic v1 responses for normal, pending, empty and error cases. Add equivalent v2 fixtures. Compare account IDs, currency, balances and transaction IDs after normalization.
Structured errors deserve product design
A request can succeed over HTTP while the underlying institution needs attention. Parse errlist, preserve unknown fields safely and show a stale state rather than a misleading green badge. Classify errors into retry, user reauthorisation and support paths without exposing credentials.
Low-risk migration plan
Freeze representative v1 fixtures
Include multiple accounts, pending records and errors.
Add version-aware transport
Request the version explicitly and record it in metadata.
Normalize both parent models
Map Organization and Connection into the same internal type.
Render `errlist` safely
Classify failures and redact secrets.
Test optional filters
Compare balance-only and account-filtered results with full reads.
Canary v2
Enable a small number of connections and reconcile counts and balances.
Keep rollback
Retain v1 parsing until provider support and telemetry justify removal.
Compatibility remains provider-specific
The changelog defines the protocol, but each provider determines when it serves a version. Request v2 only where documented. Do not infer that v2 provides longer history, webhooks or payment initiation—it does not.
Where v2 pays off first
Balance dashboards can fetch less data. A failed account can be retried in isolation. Structured errors make support and health screens far more honest. These improvements are intentionally operational; reliable finance software benefits more from clear failure states than from flashy features.
Release criteria
A migration is complete when normalized behavior matches: same remote account identities, same currency interpretation, no duplicate or missing transaction IDs across the overlap, actionable errors and a per-connection rollback path.
v1 and v2 at a glance
| Area | v1 | v2 |
|---|---|---|
| Parent model | Organization | Connection |
| Error field | `errors` | Structured `errlist` |
| Balance-only reads | Not standardized | `balances-only=1` |
| Account filtering | Filter client-side | `account=` query |
| Migration posture | Stable baseline | Adapter plus canary |
| Payments | Not included | Not included |
The design remains a small read-only contract.
Practical recommendation
If you maintain a library, expose one stable domain model and keep version handling inside the transport adapter. If you maintain an app, add a small diagnostics panel showing provider, protocol version, last source refresh and last successful import. That panel will save more support time than a silent automatic migration.