Back to Blog

Open Banking API Version Upgrades: A Regression Testing Checklist

6 min read

By OpenFinanceTools · Updated

Start with the contract your application actually uses

An API upgrade can return HTTP 200 and still break your application. A balance may change representation, an unfamiliar status may reach a switch statement, or a pagination link may point at the old endpoint. The practical question is whether the new interface preserves the behavior your customer journey depends on.

This guide describes an engineering test plan, not a certification checklist. It applies to a consumer migrating between documented versions of a provider API. The local example uses invented account data and catches a few consumer-contract failures. It makes no request to a bank and does not establish compatibility with any particular standard.

Create a migration record before changing the base URL. Record the provider, source and target versions, documentation revision, environment, endpoint list, authorization configuration, consent types, and retirement dates supplied by the provider. Keep publication dates separate from implementation dates. An announced release may not yet be available in your sandbox.

Link the record to the provider’s actual release notice. The Bank of APIs release page is an example of where institution-specific changes are communicated. The Open Banking change-management guidance also distinguishes implementation and communication concerns. Neither replaces the migration instructions for your own provider.

Build a regression matrix around observable outcomes

AreaExerciseAcceptance evidence
Account dataOptional fields absent, extra fields present, empty account listConsumer renders deliberately and preserves identifiers
AmountsZero, negative balance, precision limitsNo conversion through imprecise floating-point arithmetic
PaginationMultiple pages, repeated cursor, last pageNo missing or duplicated records; loop limit enforced
AuthorizationExpired token, wrong audience, missing scopeFailure remains distinguishable and does not become an empty account list
ConsentRevoked, expired and insufficient permissionsNo unauthorized data is returned or cached for display
Operations429, timeout and unavailable upstreamBounded recovery with useful diagnostics

Choose assertions from the documented contract. Requiring every response byte to equal an old fixture can reject harmless additions. Ignoring every difference can hide a changed financial meaning. Assert the fields your consumer uses, validate their types, and separately test behavior when an enum gains a value. For unfamiliar states, an explicit “not supported yet” result is often safer than silently selecting the default branch.

Build fixtures from synthetic data or properly sanitized samples. Replacing a customer name is not sufficient if account numbers, tokens, consent identifiers or transaction descriptions remain. Keep fixtures in version control alongside the reason each one exists.

Run a small consumer-contract exercise

The downloadable Node.js exercise accepts an extra nickname, rejects a missing identifier and a numeric balance, rejects a lower-case currency code, and accepts a small negative balance. These are deliberately chosen consumer requirements for this example; do not infer that every bank uses these field names or two decimal places for every currency.

Run it with Node.js 22 using the command below. A failed assertion exits nonzero, making the same file usable in a CI job. Extend the contract with your actual currency precision rules, timestamp requirements and documented status handling. Keep the old fixture while adding the target-version fixture so you can see precisely which assumption changed.

Download the runnable exercise

node api-upgrade-lab.mjs
View the complete exercise
import assert from 'node:assert/strict';
// Synthetic consumer contract, not a bank schema or conformance suite.
function account(response) {
  assert.equal(typeof response.id, 'string');
  assert.ok(response.id.length > 0);
  assert.match(response.currency, /^[A-Z]{3}$/);
  assert.match(response.balance, /^-?\d+\.\d{2}$/);
  return {id: response.id, currency: response.currency, balance: response.balance};
}
const baseline = {id:'demo-1', currency:'GBP', balance:'12.30'};
assert.deepEqual(account({...baseline, nickname:'Savings'}), baseline);
assert.throws(() => account({...baseline, id:undefined}));
assert.throws(() => account({...baseline, balance:12.3}));
assert.throws(() => account({...baseline, currency:'gbp'}));
assert.deepEqual(account({...baseline, balance:'-0.01'}), {...baseline, balance:'-0.01'});
console.log('5 upgrade contract checks passed');

Schema tests cannot prove that existing user consent survives a version switch. Ask the provider whether a consent created under the previous version can be used on the new resource endpoints, whether permissions change, and whether reauthorization is required. Encode the answer as a test rather than assuming backwards compatibility.

Run a complete synthetic journey in the approved sandbox: create consent, authorize, exchange the code, read the resource, revoke consent, and attempt the read again. Also test an interrupted authorization and a token that expires between requests. Track correlation IDs and error categories while excluding authorization codes and bearer tokens from logs.

If the security profile changes, use the FAPI integration guide to separate client authentication, authorization requests and token binding. The JWT tool can help inspect synthetic token structure, but decoding a token is not verification of its signature or acceptance by the provider.

Roll out reads carefully and keep writes isolated

For read-only calls, a controlled comparison can reveal differences in normalization and pagination. Compare the same logical query at an appropriate time, allowing for data that legitimately changes between calls. Record identifiers, record counts and relevant financial fields rather than storing entire sensitive responses indefinitely.

Do not duplicate payment submissions to compare two API versions. Use isolated sandbox accounts and explicit test transactions. For production payment journeys, route a business operation through one chosen version and preserve that decision across retries. A retry that silently crosses versions may encounter a different idempotency scope or consent interpretation.

Release by a small cohort with a clear rollback threshold. Measure authorization success, parsing failures, unexpected statuses and latency separately. A stable overall success rate can hide a failure affecting one institution or permission set. Review the worst-performing segment before expanding the rollout.

Make rollback and retirement part of the release

A rollback plan needs more than a configuration flag. Document whether new consents, cached tokens or persisted records created during the rollout remain valid on the previous version. If they do not, define how those operations will be completed or reconciled. Keep the provider’s incident contact and retirement window in the release record.

Before retiring the old path, confirm that scheduled jobs, background reconciliation and mobile clients no longer rely on it. Search configuration, dashboards and runbooks as well as source code. Keep the fixtures and migration notes after removal: they explain why the consumer behaves as it does and help with the next release.

Your release evidence should include the tested documentation revision, fixture results, sandbox journey outcomes, unresolved exceptions and rollback rehearsal. The JSON formatter and JSON-to-YAML converter are useful for examining synthetic examples. They do not replace schema validation or provider conformance testing.

Applying this checklist in Singapore

For an SGFinDex project, first establish the applicable participant role and documentation revision. Do not assume that a UK integration configuration transfers unchanged. The Singapore open finance and SGFinDex developer guide provides an access worksheet and suggested consent, partial-data and freshness tests to adapt to your approved interface.

Method and scope

Prepared 21 October 2026. This AI-assisted guide combines cited technical references with an illustrative engineering workflow. Its synthetic Node.js exercise is checked in the project test suite. It is not evidence of a live bank integration or certification.

Published by OpenFinanceTools. Testing, sources and corrections