Behind Fortis Bank's mobile app sits a multi-account aggregator. Checking, savings, loan balances and other-institution accounts the customer has linked all roll into one ledger view, and every transaction can carry a custom tag, a free-text note, a photo of the receipt, and the geolocation it was captured at. That feature set — described directly on the Play listing for the GRIP build (package com.fortispb.grip) — is the actual surface an integrator is querying against, not a generic "mobile banking app".
Behind the login: what the app actually carries
The Play listing names the surfaces in the app's own words. Here is the same map in the form an integrator wants it.
| Data domain | Where it lives in the app | Granularity | What integrators typically pull |
|---|---|---|---|
| Account balances | Multi-account aggregation panel | Per account, current and available | Daily balance pull for cash-flow tools, lending pre-quals, treasury dashboards |
| Transaction history | Per-account ledger, paginated | Per-transaction with amount, merchant, posted/effective date | Reconciliation, expense categorization, fraud / duplicate detection |
| Tags, notes, receipt photos, geo | Transaction detail view | Per-transaction, free-form plus binary attachment | Bookkeeping handoff, audit trail, expense-report enrichment |
| Merchant spend averages | Spending summary cards | Aggregated, multi-month | Budget engines, benchmarking, anomaly alerting |
| External-institution balances | Linked accounts the customer added themselves | Snapshot, per-source | Net-worth roll-up — better handled through a separate consent flow, see below |
| Alerts & mRDC events | Notifications and mobile deposit log | Event stream | Webhook-style triggers into back-office and accounting |
Three routes that fit this app
1. Direct authorized session against the customer's portal
The cleanest path here. The customer is already enrolled as a Fortis Internet Banking user — that is a precondition the bank itself states for using the GRIP app — so a permissioned client logs in with their credentials and pulls the same ledger surface the app does. We script the login, the four-digit-passcode step where the deployment uses it, the session refresh, and the per-account paging. Effort: low to medium for one customer, scales linearly. Durability: tracks portal changes; needs a re-validation job (see the engineering notes).
2. FDX-aligned aggregator (Plaid / MX / Finicity)
For one-off pulls into a third-party product, the aggregator route is often the right answer. Each of Plaid, MX and Finicity routinely covers small community banks like Fortis through credential-based connectors, and the CFPB has formally recognized FDX as the US standard-setting body — so the output is mapped to a stable FDX-shaped schema regardless of the front-end churn at the bank. We wire the consent screen, the token exchange and the FDX entity mapping for you.
3. Native session export (CSV / OFX / QFX)
Most US bank PFM portals expose a CSV / OFX / QFX download from inside the logged-in session; whether the Fortis deployment exposes it on this particular build is confirmed during the engagement, not asserted on this page. Where present, this is the most stable per-customer path for historical pulls. Where absent, route 1 or 2 carries the same data.
For a single business customer doing real-time book-keeping, we'd lean on route 1 for live data and let route 3 backfill the historical tail. For a fintech onboarding many Fortis customers at once, route 2 is what you ship — the consent record per customer is the asset.
A look at the client code
Illustrative outline of the route-1 flow against the customer's Internet Banking session. Endpoint paths and field names are confirmed during the build for the exact deployment — they shift between the public-banking and private-banking tenants.
import requests
# 1. Internet Banking session against the consenting customer's account.
sess = requests.Session()
sess.headers.update({"User-Agent": "fortis-grip-integration/1.0"})
login = sess.post(
"https://myaccounts.fortispb.com/auth/login",
data={"username": user, "password": pw},
)
sess.post("/auth/passcode", data={"pin": four_digit_pin}) # where present
# 2. Aggregated balance sheet across all the customer's accounts.
balances = sess.get("/api/v1/accounts").json()
# 3. Transaction stream per account, with tags / notes / geo carried through.
def pull_transactions(account_id, since):
page, out = 0, []
while True:
r = sess.get(
f"/api/v1/accounts/{account_id}/transactions",
params={"since": since, "page": page,
"include": "tags,notes,geo,attachments"},
).json()
for tx in r["items"]:
out.append({
"id": tx["id"],
"amount": tx["amount"],
"merchant": tx.get("merchant"),
"tags": tx.get("tags", []),
"note": tx.get("memo"),
"geo": tx.get("location"),
"receipt_url": tx.get("attachment_url"),
})
if not r.get("has_more"): break
page += 1
return out
What lands in your repo
Concrete deliverables for this app, scoped to its real surfaces:
- An OpenAPI 3 description of the customer-side endpoints we hit — auth, balances, transactions, attachments, alerts — with the schema mapped to FDX entities so the output is portable.
- A protocol & auth-flow report covering the login chain (username + password + passcode where present), session cookies, token refresh, and the error / lockout behaviour we observed during the build.
- Runnable client source in Python (the snippet above as a real package) and Node.js, with retry, paging and rate-limit handling.
- A contract-test suite that pins the response shape so you find out about a vendor-side change from CI, not from a broken production sync.
- Operator documentation: how the consent record is captured per customer, where it is stored, and how to revoke.
- Data-retention and US privacy notes (consent scope, withdrawal flow, data minimization defaults) so the integration plugs into your existing controls instead of fighting them.
Where the US rules sit right now for a bank this size
Fortis Bank is a small state-chartered commercial bank — per the FDIC BankFind entry, certificate #34401. The CFPB's Personal Financial Data Rights rule (12 CFR Part 1033) was finalized in October 2024 and would have sorted Fortis into the latest implementation tier; the rule has since been pulled back into agency reconsideration and is not currently enforced, so we do not present it as the governing US framework for this build. It is the forward-looking piece, not the floor.
The dependable basis today, for this specific bank, is the customer's own authorization to extract data from a session they are entitled to log into. That basis is stable regardless of how §1033 resolves. Where the customer's data also includes accounts they linked from other US banks, we route those through an FDX-aligned aggregator so each external institution gets its own consent record — that keeps the integration aligned with the FDX standard the CFPB has recognized, and keeps the audit trail clean.
Engineering notes for this exact build
What the engineering desk actually plans for on a Fortis integration:
- Two-tenant front end. Fortis runs at least two customer-facing hosts (the commercial banking site and the legacy private-banking subdomain visible from the older app builds), and the auth chain is not identical across them. We test against the host the customer actually lands on and pin the test account to the right tenant before generating fixtures — getting this wrong is the most common cause of a "works on my account, breaks on theirs" report on US community-bank integrations.
- The aggregator field is not the same as the bank field. External balances inside the GRIP view come from a PFM aggregator stitched into the bank's portal, and those rows refresh on a different cadence than the bank's own ledger. We surface a per-account
sourceandfetched_atin the output so downstream code never mistakes a stale linked-account balance for a stale Fortis balance. - Receipt photos and notes are bigger than people expect. The custom-tag / receipt-photo feature means transaction payloads carry binary attachments. We push those to object storage in your own bucket with signed URLs, not into the JSON body, so the sync stays cheap and your audit trail stays yours.
Access to a sponsor or test account, NDAs where the engagement needs them, and the customer-consent record are organised with you during onboarding — not asked of you before we start.
How the work runs, and what it costs
Source delivery for this app starts at $300, paid only after we hand over the runnable code and you've verified it pulls against your consenting test account. The other option is to skip the build entirely: call our hosted endpoints and pay per call, with no upfront fee. Either path closes in one to two weeks once we have a short requirements note and an authorised test account. Send the data shapes you actually need to /contact.html and we'll come back with a scope.
Three common shapes this takes
- Bookkeeping pull-through for a Fortis business customer. Daily balance and transaction pull, receipt photos pushed to S3, posted to QuickBooks / Xero. Route 1, one customer, runs as a script under their consent.
- Lending pre-qual. A lender wants 12–24 months of Fortis history for an applicant — route 2 via Plaid or MX with an explicit one-time consent, FDX-mapped output, results scored and discarded after the underwriting decision per the lender's retention policy.
- Fintech onboarding many Fortis customers at scale. Aggregator route end-to-end, with our consent-management UI bolted onto your sign-up flow, a webhook for revocation, and a contract-test suite running against a small fleet of sandbox accounts.
Keeping it honest after launch
The white-label PFM stack underneath GRIP gets vendor updates a few times a year, and the auth chain occasionally shifts during regulatory pushes. We bundle a contract-test pack with the delivery — it runs daily against a consenting test account and pages someone when a field name or status code moves. A revalidation pass costs less than a re-build, and clients usually keep it on retainer.
Peer apps in the same integration space
US community banks and credit unions running the same multi-account-aggregation pattern — useful if you're shopping the same integration across more than one institution. Names listed for context, not endorsement.
- Liberty Bank — Connecticut community bank running a Geezeo-powered retail / business financial-management suite alongside its mobile app.
- F&M Bank of Virginia (Squirrel) — community bank PFM with Geezeo-style aggregation and tagging behind the login.
- Community Banks of Colorado — Colorado neighbour with multi-account view, card lock, and mobile deposit, similar shape to GRIP.
- Bank of Colorado — Colorado-based personal and small-business banking app, comparable surfaces.
- Alliant Credit Union — large US credit union, Geezeo's early white-label PFM adopter, aggregation built into the app.
- Stanford Federal Credit Union — long-running Geezeo PFM integration on its consumer app.
- Partner Colorado Credit Union — regional CU with a Geezeo-powered front end.
- Regions Bank — larger US bank also on a Geezeo-derived PFM, useful as the high-volume version of the same integration pattern.
Questions integrators ask about this build
Is Fortis Bank itself covered by §1033, and does that change anything about this build?
Fortis Bank is a small state-chartered community bank (per the FDIC BankFind record, certificate #34401). Under §1033 as finalized in October 2024 it would have sat in the latest implementation tier, but that rule is currently in reconsideration and not in force. We do not rely on it. The basis for this build is the customer's own consent to extract their data from a session they are entitled to log into — that basis works today and survives the rule's outcome.
The GRIP app merges Fortis accounts with balances from other banks. Do you pull those too?
Only with the customer's blessing and only the parts they're authorized to see. The aggregated rows that appear inside their Fortis session — including external-institution balances they linked themselves — are part of the visible ledger and reachable from that session. For a cleaner take on external accounts we usually wire those through an FDX-aligned aggregator (Plaid, MX or Finicity) so each external bank gets its own consent record.
What happens to the integration when the bank's PFM front end changes?
We assume it will. The white-label PFM stack behind GRIP gets vendor updates a few times a year, and field names drift. We ship the integration with a contract-test suite that fails loudly when the response shape changes, and we keep a maintenance retainer or one-shot revalidation pass as part of the engagement so the drift gets fixed before it surprises you.
Sources and method
Notes built from the Fortis Bank Play Store listing (com.fortispb.grip), the bank's own commercial-banking site (fortisbankus.com), the FDIC BankFind institution record (certificate #34401), and the current public status of the CFPB Personal Financial Data Rights rule (CFPB §1033 finalization release) cross-checked against later reconsideration coverage. App-vendor identification is hedged because the white-label PFM provider is not asserted on the listing.
Prepared by OpenBanking Studio's integration desk, May 2026.
Fortis Bank — a brief recap
Fortis Bank is a US commercial bank headquartered in Denver, Colorado, supervised by the FDIC under certificate #34401 (state-chartered, Fed nonmember). The institution was originally established in May 1997, operated as Fortis Private Bank from 2016, and adopted the Fortis Bank name on its more recent rebrand. The consumer mobile app — package com.fortispb.grip, marketed under the GRIP product name — is the customer-facing aggregator described above and requires an existing Internet Banking enrollment to use.