Mountain Credit Union is a small cooperative — roughly $360M in assets and around 31,000 members as of the late-2025 NCUA call report — so the integration question is not which corporate developer programme to register against. It is how to reach the member-facing surfaces the cooperative actually runs, under a basis that holds up. The cooperative’s member experience is delivered through the MountainCU Mobile app and the matching online banking portal, and the data sitting behind the login is rich: share and draft balances, a history feed that members enrich with their own tags, notes and receipt photos through Snap-A-Check, advanced card controls, monthly statements, and the MCU Money Manager aggregation panel that pulls in accounts from other institutions.
The build we run for an integrator targets that login. Member gives written authorization for a defined data scope, we drive a session against the same surface the app and the portal use, we normalise the records, and what lands at the end is runnable source plus a contract a downstream system can compile against. Nothing in that path is theoretical — it is the same shape we deliver for a community CU when the obvious "register at a developer portal" option is not the conversation.
What data sits behind the login
The table maps the data we reach to where it originates inside the app and what a downstream integrator typically does with each surface. Field names follow the way the app and Mountain Credit Union’s help pages name them where possible; the wire-level field keys are confirmed during the build against a consenting member account.
| Domain | Where it originates in the app | Granularity | What an integrator does with it |
|---|---|---|---|
| Account list & balances | Home tile — shares, draft (checking), loans, certificates | Per-account; available and current balance; product code | Cash-position views, balance-drop alerting outside the app, reconciliation against a ledger |
| Transaction history | Account detail; same feed surfaced in the portal | Per-transaction; posted/effective dates; memo; amount; running balance | Categorisation, accounting export, downstream feed for a personal-finance tool |
| Member-added metadata | Tag, note and receipt/check photo attached to a transaction | Free-text tags & note; image URL per attachment | Carrying the member’s own annotations into a third system rather than re-keying them |
| Snap-A-Check deposits | Mountain Credit Union’s branded mobile deposit flow | Deposit id; front/back image; status; amount; account | Reconciling deposit submissions and outcomes inside an internal queue |
| Statements | Statements section — PDF + electronic export | Monthly; PDF and (where the portal exposes it) OFX/QFX | Bookkeeping import, retention archive, tax workflow |
| Card controls | Mastercard debit/credit on-off, limits, geolocation guard | Per-card; on/off state; control event log | Programmatic freeze on a fraud signal, audit of who turned a card off and when |
| Money Manager aggregation | MCU Money Manager — third-party aggregation widget | External accounts (other FIs) the member has linked; refresh cadence governed by the aggregator | Member’s consolidated view, kept in its own table so it does not contaminate native CU records |
| Branch & ATM locator | Locator screen | Static reference data | Bundled into the integration documentation; rarely a primary need |
The route we take
Three authorised paths fit this app. They are not mutually exclusive; for a Mountain CU build the first carries the work, with the others as fallbacks for specific shapes.
Member-consented session against the mobile API
The member signs a scope-limited authorization, we drive an authenticated session against the same endpoints the iOS and Android apps use, and the records come out structured. This is the durable path because it follows the same surface members already exercise daily, and the credit union’s side of it does not change unless the cooperative re-platforms its mobile build. Effort: a one to two-week cycle for the typical balance + history + statement scope. Setup we handle: the consent paperwork template, the credentials exchange, the device-binding step, and the per-build re-validation harness.
Protocol analysis of the app traffic
Same target, slightly different lens — we capture the network calls the app actually makes on a consenting handset, confirm field names and pagination behaviour, and lift them into the spec. This is what makes the first path concrete rather than guesswork. It is also how we keep the integration honest when a new app version moves a field.
Native OFX/QFX export
The portal’s statement download is a useful fallback for posted history, particularly for backfill at the start of a build and for the bookkeeping-export use case. It is lower-fidelity than the mobile-API path (no tags, no images, dated to statement cycle), so we treat it as a complement rather than the primary feed.
For a typical Mountain CU integration the member-consented session does the lifting, the export covers the cold-start backfill, and the protocol-analysis pass is what keeps the contract aligned through future app revisions.
Legal basis
The credit union sits inside the US framework, where the long-running answer to "what entitles a third party to a member’s account data" was the patchwork of consumer-permissioned aggregation. The CFPB’s 12 CFR Part 1033 — the Personal Financial Data Rights rule — was finalized in October 2024, then a federal court enjoined the agency from enforcing it, and the Bureau released an Advance Notice of Proposed Rulemaking on reconsideration in August 2025. That status matters: a Waynesville credit union of Mountain’s size is not a settled "covered data provider" today, and the eventual scope of any obligation is one of the items being reconsidered. So the dependable basis we build on is the member’s own written authorization, scoped to the specific data domains, with consent records logged for audit and a revocation path the member can use without contacting us. If a reconsidered §1033 produces an obligation that Mountain Credit Union must meet by exposing a defined consumer-data surface, we re-point the integration at that surface; we do not pretend the obligation exists today.
On the technical-standards side, the FDX data-sharing specification is the closest thing to an industry-agreed shape for US consumer-financial data; we keep the normalised output we hand back aligned with FDX field names where the data maps cleanly, so a future migration onto an FDX-compliant feed is not a rewrite.
How the calls actually look
Illustrative shape of a member-consented session against the mobile surface — endpoint paths, header names and JSON keys are confirmed during the engagement against a sandbox or a consenting member’s account, not asserted blind here.
import httpx, datetime as dt
# 1. Authenticate. The app combines a username/password pair with a
# four-digit transaction PIN; biometric on the device unlocks a
# stored session rather than replacing the underlying auth.
async def open_session(client, username, password, pin, device_id):
r = await client.post(
"/auth/v1/login",
json={"u": username, "p": password},
headers={"X-Device-Id": device_id, "X-Client": "mcu-mobile"})
token = r.json()["session"]["token"]
await client.post(
"/auth/v1/transaction-pin",
json={"pin": pin},
headers={"Authorization": f"Bearer {token}"})
return token
# 2. Account list. Product codes distinguish share, draft, loan and
# certificate accounts; we lift the credit-union-native ones and
# keep the Money Manager aggregated rows in a separate table.
async def list_accounts(client, token):
r = await client.get("/accounts/v2/summary",
headers={"Authorization": f"Bearer {token}"})
return [{
"id": a["accountId"],
"product": a["productCode"], # SHR / DFT / LOAN / CD
"nickname": a.get("nickname"),
"available": a["availableBalance"],
"current": a["currentBalance"],
"source": "mountaincu",
} for a in r.json()["accounts"]]
# 3. History with member-added metadata. Tags, the note and any
# receipt/check image attached through Snap-A-Check ride on the
# same record — we surface them as first-class fields.
async def history(client, token, account_id, since: dt.date):
page = 1
while True:
r = await client.get(
f"/accounts/v2/{account_id}/history",
params={"from": since.isoformat(), "page": page, "size": 100},
headers={"Authorization": f"Bearer {token}"})
body = r.json()
for tx in body["history"]:
yield {
"id": tx["transactionId"],
"posted": tx["postedDate"],
"effective": tx.get("effectiveDate"),
"amount": tx["amount"],
"memo": tx.get("description"),
"tags": tx.get("memberTags", []), # member-added
"note": tx.get("memberNote"), # member-added
"image_url": tx.get("attachmentUrl"), # Snap-A-Check
}
if not body.get("hasMore"): break
page += 1
Deliverables
For a Mountain CU build the package that lands at the end of the engagement is concrete:
- An OpenAPI 3 spec covering the account, history, statement, card-control and Snap-A-Check surfaces actually wired up, with the member-added tag/note/image fields modelled in the response schemas instead of glued on.
- A protocol & auth-flow note — what the login chain looks like (username + password + transaction PIN + device binding), how the session token is refreshed, where biometric unlock sits relative to it, and which errors mean "re-prompt the member" rather than "retry quietly".
- Runnable source for the endpoints above in Python (httpx) and Node.js (fetch), with a typed return shape and a fixture set captured from the consenting member’s account.
- A normalised output schema that lines up with FDX field naming where it maps cleanly, so a future move onto a §1033-compliant feed or an aggregator-backed feed is a wiring change, not a re-modelling exercise.
- Automated tests: contract tests against the captured fixtures, a re-validation script for new app builds, and a thin end-to-end harness that exercises login → list → history → statement.
- Interface documentation and a short compliance brief — the consent scope, the retention defaults, what we log and what we deliberately do not.
Build notes — three things we account for on this app
Member-added metadata round-trips with the transaction id. The tag, free-text note and Snap-A-Check image a member attaches in the app are persisted server-side against the same transaction record, not a side channel. We model the integration’s schema so they stay linked to that record after the inevitable posted-date adjustment when a pending transaction settles. The metadata is the most underrated part of this surface; mis-modelling it is the most common way an integration loses fidelity.
The auth chain is password + transaction PIN + device binding, with biometric on top. Biometric is a local-unlock layer over a stored token, not a replacement for the credential exchange. A long-running integration that ignores the device-binding step ends up silently re-triggering the new-device challenge in the member’s app every few weeks. We bind the integration to its own device identity, refresh the token on the schedule the server expects, and log the refresh outcome so a drift shows up as a test failure rather than as a member complaint.
Money Manager is aggregated, not native. MCU Money Manager presents accounts the member holds at other institutions through an aggregation provider inside the credit-union portal. Those records carry that provider’s refresh cadence and terms. We keep them in a distinct table from the native Mountain CU shares, drafts, loans and certificates so a downstream consumer never mixes Mountain-originated balances with externally-aggregated ones — the two have different freshness and different authorities.
Interface evidence
Screens lifted from the public store listing, kept for context. Click to enlarge.
Pricing & timeline
Source-code delivery starts at $300 for a Mountain CU build — and you only pay after we hand the work over and you have run it against a sandbox or a consenting member account. You get the OpenAPI spec, the runnable Python and Node.js source for the surfaces in scope, the tests and the documentation, all yours to host and modify. If you would rather not run any of it, the second arrangement is a pay-per-call hosted API: we operate the endpoints, you pay only for the calls you make, with no upfront fee. The build cycle is one to two weeks once the scope is defined; ongoing re-validation against new app versions is a small retainer either way. The point of contact for either path is our contact page — give us the data scope you need and we will come back with a fixed delivery for the cooperative.
Questions integrators ask about MountainCU Mobile
Does MountainCU Mobile expose member-added transaction tags and receipt photos to an integration?
Yes. Tags, the free-text note and any receipt or check images that a member attaches in the app are persisted server-side against the same transaction record, so they come back through the history endpoint as first-class fields. We model them that way in the schema rather than scraping them out of a separate surface.
How do we treat the MCU Money Manager aggregated accounts?
Separately. Money Manager pulls accounts the member holds at other institutions into the credit-union portal through an aggregation provider, so those records carry that provider’s terms and refresh cadence. We keep them in a distinct table from the native Mountain CU shares, drafts, loans and certificates so a downstream consumer never mixes the two.
What changes when Mountain Credit Union ships a new app build — does the integration break?
Mobile builds churn faster than the credit-union core. We pin the auth and history calls to a versioned contract, run a re-validation pass against a consenting member account whenever the build number changes, and surface drift as a failed contract test before it reaches production.
Is the CFPB’s personal financial data rights rule the legal basis for this work?
Not today. 12 CFR Part 1033 was finalized in October 2024 but a federal court has enjoined the CFPB from enforcing it, and the agency reopened the rule for reconsideration in August 2025. We build on the dependable basis instead: a written member authorization for the specific data scope, with consent records logged for audit. If §1033 lands in a form that obliges Mountain Credit Union to publish a developer interface, we switch the build over to that surface.
Sources & review
For this brief we read the cooperative’s digital-banking pages, the Google Play and App Store listings for the package org.mountaincu.grip, the NCUA-derived public profile, the CFPB’s reconsideration notice for §1033 and the FDX specification homepage. Specific sources used:
- Google Play listing — MountainCU Mobile
- Mountain Credit Union — Online & Mobile Banking
- CFPB — Personal Financial Data Rights Reconsideration
- Financial Data Exchange — FDX specification homepage
Mapping reviewed 2026-05-29 by the OpenBanking Studio integration desk.
Other NC credit-union apps in the same shape
An integrator targeting Mountain CU often has the same need at other North Carolina cooperatives — same authenticated-portal pattern, same data domains, same legal basis. Useful neighbours, listed neutrally:
- SECU — State Employees’ Credit Union of NC, the state’s largest cooperative; the mobile app exposes the same domain set at a much larger member scale.
- LGFCU Compass — Local Government Federal Credit Union’s mobile app, with its own money-management surface that pulls in external accounts.
- Self-Help Credit Union — Durham-headquartered, with a member-facing mobile app covering balances, history, transfers and mobile deposit.
- Coastal Credit Union — Raleigh; the app adds Zelle and a stronger budgeting surface alongside the standard banking domains.
- Allegacy Federal Credit Union — Winston-Salem; comparable digital banking surface, with wellness-themed adjuncts.
- Truliant Federal Credit Union — Winston-Salem; member self-service for balances, transfers and statements.
- Telco Community Credit Union — Asheville, another western-NC cooperative; similar field-of-membership shape to Mountain CU.
- Champion Credit Union — Canton, western NC; the closest geographic peer with a member-facing mobile build.
- My Credit Union — community CU mobile app sharing the same authenticated-portal pattern.
About Mountain Credit Union (collapsed profile)
Mountain Credit Union is a not-for-profit, member-owned cooperative headquartered in Waynesville, North Carolina. It operates under a state charter (chartered Jan 1, 1963 per public credit-union directories) and serves a field of membership covering twelve western-NC counties: Buncombe, Cherokee, Clay, Graham, Haywood, Henderson, Jackson, Macon, Madison, McDowell, Swain and Transylvania. Public NCUA-derived directories report it at roughly $360M in assets and around 31,000 members as of late 2025; those figures move with each call-report cycle. The cooperative’s member-facing digital surfaces are the MountainCU Mobile app (Android package org.mountaincu.grip; iOS app id 1532105988) and the matching online-banking portal. References to MountainCU Mobile on this page are for the purpose of describing an independent integration approach.