open-banking-io (Python)
Server-to-server client for open-banking.io. It authenticates with your API key and decrypts the zero-knowledge data envelopes locally with your exported private key — the service only ever returns ciphertext it cannot read.
pip install open-banking-io
from open_banking_io import OpenBankingClient
# Load the credentials .json you exported from the app (API key + private key).
with OpenBankingClient.from_credentials("credentials.json") as client:
for account in client.get_accounts():
booked = next((b for b in account.balances if b.type == "ITBD"), None)
label = account.display_name or account.owner_name
print(f"{label} {account.iban}: {booked.amount if booked else None} {account.currency}")
page = client.get_transactions(account.id, limit=50)
for t in page.items:
print(
f" {t.booking_date} {t.creditor_name or t.debtor_name} {t.amount} {t.currency}"
)
# Trigger an online sync (decrypts the account uid locally and posts it):
client.sync(account.id)
Or construct it explicitly:
client = OpenBankingClient(api_base_url, api_key, private_key_pkcs8)
API
get_accounts() -> list[Account]— decrypts each account's envelope, display name and balances.get_transactions(account_id, *, date_from=None, date_to=None, limit=None, offset=None) -> TransactionPageget_connections() -> list[Connection]sync(account_id) -> SyncResult— decrypts the account uid locally and posts it.sync_all() -> SyncAllResult— syncs every account that has an active session.
Amounts are exposed as decimal.Decimal. Models are plain @dataclasses.
When the client constructs its own httpx.Client it applies a default 30s timeout and sends a User-Agent: open-banking-io/python/<version> header on every request (a caller-supplied client is left untouched).
Diagnostics
When a call fails before any HTTP response, diagnose() probes each stage in turn and
returns a report that is safe to paste into a support ticket:
with OpenBankingClient.from_credentials("credentials.json") as client:
print(client.diagnose().report())
[PASS] base_url 'https://open-banking.io' -> host='open-banking.io' port=443 scheme=https (0 ms)
[PASS] dns open-banking.io -> 104.21.78.242, 172.67.138.186 (24 ms)
[PASS] tcp_connect connected to open-banking.io:443 (10 ms)
[PASS] tls_handshake TLSv1.3 TLS_AES_256_GCM_SHA384 issuer='Google Trust Services' notAfter=Nov 5 13:47:21 2026 GMT (40 ms)
[PASS] api_preflight GET api/accounts -> HTTP 200 (159 ms)
It never raises: a failing stage is recorded and the stages that depend on it are skipped, so a DNS problem reads differently from a TLS problem or a rejected API key. The report carries no API key, no private key, no decrypted data and no response bodies; any credentials in the base URL are stripped, and proxy and CA environment variables are listed by name with their values withheld.
The api_preflight stage always runs, even when the direct probes fail: those open their own
sockets and so bypass a proxy or a custom TLS setup, which can make them report a fault on a
connection that works. The verdict comes from the request the SDK actually makes.
as_dict() returns the same data as JSON-serialisable structures.
Request logging is opt-in through the standard logging module and records only the method,
path, status and duration — never headers or bodies:
import logging
logging.basicConfig()
logging.getLogger("open_banking_io").setLevel(logging.DEBUG)
Encryption
Envelopes use ECDH P-256 → HKDF-SHA256 → AES-256-GCM. Decryption requires the private key from
your credentials bundle and happens entirely in-process. Full wire format and the other language
clients: repo README ·
THREAT_MODEL.md.
Development
python -m venv .venv
.venv/bin/pip install -e .[dev]
.venv/bin/pytest -q
MIT licensed.
Metadata
Release files for open-banking-io 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| open_banking_io-1.2.0.tar.gz | 21.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| open_banking_io-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.0 kB
Release files / open_banking_io-1.2.0.tar.gz
| Download URL | open_banking_io-1.2.0.tar.gz |
|---|---|
| Size | 21.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
34fe135a9829d33add57a87c5caedf321a932134d734e61148827d217016ff25
|
|
BLAKE2b-256 checksum How to use checksums |
8f66dc789f864a18dd7c37f51bca4131e1cb5a8ca72a835e5e9d723f918c8574
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.
Transparency logRelease files / open_banking_io-1.2.0-py3-none-any.whl
| Download URL | open_banking_io-1.2.0-py3-none-any.whl |
|---|---|
| Size | 15.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0171ba8d8be0968e7c4828e47f70ec65eb56113a67d077ea7875b68673f0e510
|
|
BLAKE2b-256 checksum How to use checksums |
72a92dd40ea182a22b24ea74ad8fda1f42454fff31fd3e52e3a51fd9179df3ea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.
Transparency log