Where this app’s data sits, and what kind of feed it wants to be
St. Johns Bank & Trust opened in St. John, Missouri in 1926 (per its own story page) and now runs a four-branch network around northwest St. Louis with assets reported around US$299M on third-party financial profile data — small enough that none of the large data aggregators (Plaid, Finicity, MX) treats it as a tier-one direct connection, large enough that a serious integration is a one-shot scoping job rather than a generic library wrap. The mobile app whose Android package is com.stjohnsbank.grip is the customer-facing surface and the only realistic ingestion point. The grip suffix is not incidental: it names the white-label mobile-banking platform Banno (acquired by Jack Henry in 2014) sold into community banks before the platform was rolled forward; the session shape is familiar from a long tail of similar deployments.
So the build is shaped like a polling worker. One customer, one device-bound session, a delta cursor per account, two parallel pull paths (transactions and statements), and an opt-in fetch for the deposit-image archive. A national bank brings per-product variation that bloats a scope. This one does not.
What’s reachable and where it lives in the app
| Domain | Where in the app | Granularity | What an integrator typically does with it |
|---|---|---|---|
| Accounts & balances | Home dashboard after passcode/biometric unlock. | Per account: current and available, last update time. | Drive a balances widget; trigger threshold alerts in the consumer stack instead of the app’s native one. |
| Posted transactions | Per-account history tab. | Line-level: amount, posted date, description, category (where tagged), memo, attached photo/receipt id. | Bookkeeping ingest, reconciliation, expense routing, tax export. |
| Pending transactions | Same tab, separately flagged in-app. | Line-level with a pending status and an expected post date. | Cash-flow projection; release-on-post webhooks. |
| Monthly statements | Statements section — the app advertises view-and-save. | PDF per account per month, plus availability date. | Archive, automated audit, OCR for legacy data warehouses. |
| Mobile-deposit images | Deposit-by-photo flow. | Front and back JPEG per deposit, tied to a transaction id once posted. | Optional check-image archive for compliance or accounting workflows. |
| Transfers and P2P payments | Move money / pay-a-friend tabs. | Per transfer: source, destination, amount, status, scheduled or recurring marker. | Treasury / sweep automation; outbound payment-orchestration glue. |
| Alerts | Notification preferences. | Threshold rules per account, channel preference. | Mirror the rules in the consumer stack so notifications stay coherent across apps. |
Routes that actually apply for a bank of this shape
Three routes are worth considering for St. Johns Bank, in roughly the order we’d pick them.
1. Authorized mobile-session integration (the spine)
The customer authorizes us, in writing, to enroll an integration device against their account using the same flow the consumer app uses. Once enrolled, we hold a long-lived session and poll for deltas on the customer’s behalf. Effort: about a week of session capture and field mapping, plus a couple of days on retries and error handling. Durability: high — the session model is part of the platform and survives backend rollouts. Coverage: every domain listed in the table above. This is the route we recommend in almost every case for an app of this size.
2. Aggregator passthrough via Plaid / Finicity / MX
The same data, surfaced through an aggregator’s credential-based connection. Effort is lower at first because the aggregator’s SDK is already written. Coverage is narrower (typically balances and posted transactions only, no check images, statements often patchy) and rate-card economics may not work at small per-customer volumes. Useful as a fallback or a bridge for the first few weeks of a build while the spine route is being scoped.
3. Native export plus a thin reconciler
The app advertises monthly statement save and the consumer can request CSV/OFX through online banking. For workloads that only need monthly reconciliation, a small worker that drives the export and parses it is the cheapest thing to ship. It is not enough for any consumer needing near-real-time, but for a once-a-month sweep it is hard to beat.
A polling worker, sketched
Illustrative only — the exact field names get pinned during the build against the live mobile session, then frozen behind the OpenAPI shape we hand over so consumers never see the bank’s wire format.
# st_johns/sync.py — delta poller for one consented customer account.
# The shape (cursor + items + next_cursor) is what we deliver downstream;
# the bank's actual wire is pinned during the session-capture phase.
import httpx
from .session import StJohnsSession, SessionExpired
from .store import upsert_txn, last_cursor, save_cursor
def sync_account(session: StJohnsSession, account_id: str):
cursor = last_cursor(account_id)
page = 0
while True:
try:
body = session.get(
f"/accounts/{account_id}/transactions",
params={"after": cursor, "limit": 200},
)
except SessionExpired:
session.re_enroll() # one consent prompt, then resume
continue
for tx in body["items"]:
# write-once on (account_id, txn_id); pending and posted
# land in the same table with a status flag.
upsert_txn(account_id, tx)
cursor = body.get("next_cursor")
page += 1
if not cursor:
break
save_cursor(account_id, cursor)
return {"account_id": account_id, "pages": page}
What gets handed over at the end of the build
We ship the bits a backend team can drop in and run, not a binder.
- Runnable Python client for the session, polling worker and the statement/image fetchers, with a worked example against a consenting test account.
- Node.js client covering the same surfaces, generated against the same OpenAPI shape, for stacks that don’t want a Python dependency.
- Webhook adapter for downstream consumers — the worker emits posted-transaction events to HTTPS callbacks the consumer registers, with an HMAC signature header the consumer verifies; an SQS or NATS sink is a flag flip.
- Test harness covering session expiry, cursor resume, pending-to-posted transitions, statement availability, and check-image opt-in; runs in CI with recorded fixtures so a backend change at the bank gets caught the morning after.
- OpenAPI 3.1 specification for the downstream-facing shape, plus the auth-flow report (device enrollment, session refresh, revocation, the passcode/biometric step boundaries).
- Interface documentation for engineers picking the integration up later, with a one-page operator runbook for the polling worker.
- Data-retention guidance sized to this bank and US data-rights expectations (see the next section).
How the sync stays current without prompting the customer constantly
The default cadence is conservative on purpose. St. Johns Bank’s feed posts intraday but not in real time, so a worker that polls every few minutes wastes calls. Four-to-six hours catches every same-day post that matters for a downstream dashboard, fits inside the bank’s implicit fair-use envelope for a single-customer session, and keeps the session refresh count low — which is the variable that drives whether the customer ever sees a passcode prompt they didn’t expect. When a consumer-facing surface needs tighter timing (a real-time ledger view, a low-balance warning), we move the affected accounts onto a 15-minute path and charge for the extra calls on the hosted route. Statement and check-image pulls run on event triggers (statement-available, deposit-posted) rather than on the polling clock.
Where US data-rights rules sit for a bank this size
St. Johns Bank is FDIC-supervised under certificate #8898 and chartered through the Missouri Division of Finance. The CFPB’s Personal Financial Data Rights rule (12 CFR Part 1033) was finalized in October 2024 and would, as finalized, have phased compliance obligations onto depository institutions by asset size — but as of this writing the rule has been enjoined in the Eastern District of Kentucky and the Bureau has reopened it for reconsideration (Federal Register 2025-16139, ANPRM published August 22, 2025; comment window closed October 21, 2025). So §1033 is not the basis we build against today. The basis is the customer’s own written authorization to access their account — scope limited to the domains the integration actually needs, revocable at any time, session credentials held under the customer’s control, every call logged. If §1033 lands close to its finalized shape the integration moves onto whatever access channel the bank’s core servicer publishes; until then, the spine is consented access. NDAs apply where the customer is a corporate treasury rather than an individual.
Notes from scoping a build like this
A few things we account for up front, so they don’t surprise either side later in the build.
- Device-binding and the passcode boundary. The Grip-derived mobile session is provisioned per device and the consumer flow gates active use behind a four-digit passcode or biometric, per the app’s own description. We design enrollment around that gate rather than around it — the integration device gets registered once, with the customer’s authorization, and after that the polling worker runs on the long-lived session token without ever asking the customer for the passcode again. That keeps the prompt count low and avoids the prompt-storm a naive scraper would produce.
- Statements and live transactions are two surfaces, not one. The monthly statement (PDF) and the live transaction feed live behind different endpoints in the app. We map them as two ingestion paths — a daily delta sync for transactions, an event-triggered pull on statement availability — so a downstream consumer that only wants the PDF doesn’t pay the polling cost of the transaction feed, and a consumer that wants the live feed doesn’t wait on PDF generation.
- Check images carry different rights than transaction lines. The mobile-deposit capture uploads front and back JPEGs server-side. Pulling those back out for archive is technically the same session, but legally a wider grant. We carve it out as an opt-in flag per customer so the default integration doesn’t accidentally hoover images a downstream consumer never asked for.
- The four-branch reality means slow backend changes. Banks this size do not push hot fixes to a mobile platform weekly. The session shape we capture in week one is, in practice, the shape that holds for the contract period. The test harness keeps a recorded-fixture probe that runs every morning, so a quiet field rename on the bank’s side becomes a red build on ours the same day the change ships.
How this brief was put together
Public sources only, opened directly: the bank’s own digital banking and story pages, the Google Play listing for com.stjohnsbank.grip, the FDIC’s BankFind entry for certificate #8898, the CFPB’s §1033 reconsideration record, and trade reporting on community-bank data-aggregation practice. Specific citations:
- FDIC BankFind — St. Johns Bank & Trust, certificate #8898
- CFPB — Personal Financial Data Rights Reconsideration
- Federal Register — Personal Financial Data Rights Reconsideration (ANPRM, Aug 22 2025)
- Banking Dive — Small banks and fintechs ask CFPB for more time to phase out screen scraping
Mapped by OpenFinance Lab — 2026-05-31.
Other community-bank apps in roughly the same integration shape
The data and the route look broadly similar across small Missouri-region institutions; an integrator scoping more than one will usually find the same domains and the same session pattern, just renamed.
- Bank of Old Monroe — community bank serving northeast Missouri; transactions, transfers, mobile deposit and bill pay in the consumer app.
- Midwest BankCentre — St. Louis community bank with personal and business mobile banking, similar mobile-deposit surface.
- Reliance Bank — mid-sized Missouri community bank, comparable account and statement surfaces.
- Community Bank of Missouri — CBOM Mobile carries the same balance, transfer and deposit pattern.
- First Mid Bank & Trust — Illinois/Missouri community bank running a similar mobile app shape.
- First Community Credit Union (St. Louis / Chesterfield / St. Charles) — member-side equivalent with money-management overlay.
- Neighbors Credit Union — St. Louis credit union with a comparable consumer-facing mobile app.
- St. Louis Community Credit Union — the Softek-based mobile app covers the same balance / transaction / transfer set.
Questions a St. Louis fintech usually asks first
How often does the sync run, and what does it return per poll?
For St. Johns Bank we run the delta worker on a four-to-six hour cadence by default. The bank’s transaction feed posts intraday but not in real time, so anything faster mostly returns an empty page. Each poll asks for transactions after the last cursor we stored; the response carries posted and pending lines, and we forward both downstream with a status flag. Tighter cadences are available where a customer-facing dashboard needs near-real-time and are billed on calls.
Does the mobile-deposit check image flow come along with the transaction sync?
Not by default. The image route is a separate surface inside the app and we wire it as an opt-in fetch keyed on the transaction id once the deposit posts. If a build only needs amounts, dates and memo lines, we leave the images alone, which keeps the storage footprint and the rights conversation smaller.
We are a St. Louis fintech — does a four-branch community bank like this take longer to build than a national bank app?
Usually shorter. The Grip-derived mobile session St. Johns Bank runs has a stable shape: one customer, a handful of accounts, monthly statements, transfers between them. There is no per-product variation that lengthens a megabank scope. Our usual cycle is one to two weeks from first session capture to a runnable client and a test harness; access arrangements and any onboarding paperwork are handled with you inside that window.
What happens to the worker when the customer changes their passcode or re-enrolls a device?
The worker treats it as a forced re-enrollment. The session token aged out is detected on the next poll (a 401 on the transactions endpoint), and the customer is prompted once through the consent surface we ship with the integration. Cursors are preserved, so the next successful poll resumes at the last delta without replaying months of history.
First captures for a bank this size usually come back inside one to two weeks — a runnable Python and Node.js client, the OpenAPI shape, the auth-flow report, the test harness. Source-code delivery starts at US$300, paid after delivery once you’re satisfied with what we hand over; the alternative is a pay-per-call hosted API with no upfront fee, billed only on the calls you actually make. Tell us the app and what you need from its data and we’ll scope it back in plain prose.
App profile (collapsed)
Name: St. Johns Bank · Operator: St. Johns Bank & Trust Company · Android package: com.stjohnsbank.grip · iOS: store id 6472681923 (current listing); an earlier listing 1099313331 also exists per Apple’s App Store. Headquarters: St. Louis, Missouri (the bank’s namesake town of St. John). Founded: 1926, per the bank’s own history page. Charter: state-chartered commercial bank, FDIC certificate #8898 per BankFind. Footprint: four branches across northwest St. Louis and St. Charles counties. App functions per the listing: tagged transactions with notes and receipt photos, balance-threshold alerts, person-to-person and bill payments, internal transfers, mobile deposit by photo, monthly statement view/save, four-digit passcode or biometric unlock. The listing notes the app is for existing online banking customers.