---
title: "Apps on BankSync"
description: "What a BankSync app is, how it differs from an API key, a destination and a client portal, and the shape of the journey from registering an app to reading bank data on your own users behalf."
section: "Apps"
canonical: "https://banksync.io/docs/apps/apps-overview"
specs: ["apps"]
operationBindings: [{"capability":"apps","operation":"apps.listing.get"},{"capability":"apps","operation":"apps.install.approve"}]
---

A BankSync **app** is your product, installed into someone else's BankSync
workspace. They own the workspace. You hold a grant against the banks they chose
to give you, you read only those, and — if you ask for it — the data arrives on
your own endpoint as it syncs.

The unit you build against is the **install**: one app, in one workspace,
holding one grant. Not a user, not a bank connection. Everything else in this
section is a detail of getting an install created, keeping it working, and
reading through it.

## Is an app what you want?

There are four ways data leaves BankSync, and picking the wrong one costs real
time. The question that separates them is **whose workspace holds the data, and
who is paying**.

| You want to…                                               | Use             | Whose workspace  |
| ---------------------------------------------------------- | --------------- | ---------------- |
| Read **your own** workspace from a script or an agent      | An API key      | Yours            |
| Push your own data into a tool you already use             | A destination   | Yours            |
| Let **your users** connect their banks and read their data | **An app**      | Each user's own  |
| Manage many clients' workspaces as their accountant        | A client portal | A child of yours |

An **API key** is a secret that gives programmatic access to *your* workspace
over the REST API and the MCP server. It is the right tool when the data you
want is already yours. It is the wrong tool for a product with users, because
you would be handing every user the same credential to your own workspace.

A **destination** — Google Sheets, Notion, a database, a webhook — pushes a
workspace's synced data out to a tool. Also yours, also not a product.

A **client portal** is a child workspace under your parent workspace, for an
accountant or bookkeeper managing clients. Every portal bills to the parent's
subscription, and the parent's owner and admins hold implicit authority over
every portal beneath it. That is exactly right for an accountant and exactly
wrong for a software product: your users would be paying through you, and you
would hold administrative access to all of their bank data. If you are building
something your users install, you want an app.

> **Who pays:** 'The builder pays for the app. A user installing your app does not need a paid BankSync plan for you to read their data through the install — the plan gates the workspace-facing API, not an app acting on a grant.'

## The shape of it

Five steps, each with its own page.

1. **Register the app.** Its name, slug, branding, and the scopes it may
   request, plus one or more client credentials. See
   [Register an OAuth app](/docs/apps/registering-an-app).
2. **Declare a manifest.** What your app reads, what furniture it creates in the
   workspace (tables, feeds, enrichment steps), and where events should be
   delivered. See [Building a BankSync app](/docs/apps/apps-reference).
3. **Send users to the connect link.** `https://app.banksync.io/connect/<slug>`
   — BankSync shows them who is asking and for what, signs them in or signs them
   up, walks them through connecting their bank, takes their approval, and hands
   them back to you with an authorization code. See
   [The connect link](/docs/apps/connect-link).
4. **Read, and receive.** Exchange the code for a token and read `/v1` on that
   user's behalf; take signed events on your endpoint as their data syncs.
5. **List it**, if you want to be found. See
   [Listing and publishing your app](/docs/apps/app-listing).

Your users never see a BankSync workspace, dashboard or navigation at any point
in that flow. The connect page renders before anyone signs in, on purpose: the
person following it has usually never heard of BankSync, and they should learn
who your app is and what it will read before they are asked to make an account.

## Returning users

A user who already installed you and needs to add a second bank does **not** go
back through the full flow. The connect link takes an `intent`:

```text
https://app.banksync.io/connect/<slug>?intent=add_bank&return_to=https%3A%2F%2Fyourapp.example%2Fdone
```

`intent=add_bank` skips the gate and the consent screen — they already installed
you and already saw what you can read — runs the bank step, and returns them to
your own page. `intent=reauth` does the same for one connection that has broken.
Neither mints a new authorization code, because you already hold a grant.

Note there is no workspace id anywhere in that URL. A third party cannot know
which workspace a browser is signed in to, and with the connect link it does not
need to.

> **One gap to design around:** 'The install path is built end to end and the platform is live in production. One gap worth knowing before you design around it: connection.created is delivered once per bank, the first time it reports healthy, and no event tells you a connection has RECOVERED from requires\_reauth. Building a BankSync app marks which side of that line each feature is on.'

## Next

- [Register an OAuth app](/docs/apps/registering-an-app) — the app record, its
  client credentials, and the redirect URIs every return URL must match.
- [Building a BankSync app](/docs/apps/apps-reference) — the manifest contract,
  the install lifecycle, your endpoint and its signed events.
- [The connect link](/docs/apps/connect-link) — every query parameter, the three
  intents, the `return_to` rules, and the round trip back.
- [Listing and publishing your app](/docs/apps/app-listing) — review, and being
  found.
