> ## Documentation Index
> Fetch the complete documentation index at: https://sammydocs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart: link an account

> Open Connect.js, receive an auth code, and exchange it for a Mono account ID on your backend.

Use this guide to open Connect.js, receive an auth code, and store the resulting Mono account ID from your backend.

## Before you start

You need:

* a Mono application
* its public key for the browser
* its secret key stored only on your backend
* Node.js 10 or later

Get application keys from the [Mono dashboard](https://app.mono.co/apps/).

## 1. Install Connect.js

```bash theme={null}
npm install @mono.co/connect.js
```

## 2. Create the widget

For a new customer, pass a name and email. If the customer already exists in Mono, pass `{ id: "CUSTOMER_ID" }` instead.

```javascript theme={null}
import Connect from "@mono.co/connect.js"

const connect = new Connect({
  key: "PUBLIC_KEY",
  scope: "auth",
  data: {
    customer: {
      name: "Ada Lovelace",
      email: "ada@example.com"
    }
  },
  onSuccess: handleSuccess,
  onClose: () => console.log("User closed Connect"),
  onEvent: (eventName, data) => {
    console.log(eventName, data)
  }
})

connect.setup()
```

`setup()` mounts the widget but keeps it hidden. Create the instance once for the lifetime of the page or component.

## 3. Open the widget from a user action

```html theme={null}
<button id="link-account" type="button">
  Link a financial account
</button>
```

```javascript theme={null}
document
  .querySelector("#link-account")
  .addEventListener("click", () => connect.open())
```

The user completes institution selection and authentication inside the hosted widget.

## 4. Send the auth code to your backend

After account linking, `onSuccess` receives an object containing `code`. Forward that code to your backend.

```javascript theme={null}
async function handleSuccess({ code }) {
  const response = await fetch("/api/mono/exchange", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ code })
  })

  if (!response.ok) {
    throw new Error("Could not exchange Mono auth code")
  }

  const account = await response.json()
  console.log("Linked Mono account:", account.id)
}
```

The auth code is an intermediate result. It is not the account ID and should not be used to reauthorize an account.

## 5. Exchange the code on your backend

The backend calls Mono's token-exchange endpoint with the secret key. The example below is framework-neutral server code.

```javascript theme={null}
export async function exchangeMonoCode(code) {
  const response = await fetch("https://api.withmono.com/v2/accounts/auth", {
    method: "POST",
    headers: {
      accept: "application/json",
      "Content-Type": "application/json",
      "mono-sec-key": process.env.MONO_SECRET_KEY
    },
    body: JSON.stringify({ code })
  })

  if (!response.ok) {
    const error = await response.text()
    throw new Error(`Mono token exchange failed: ${response.status} ${error}`)
  }

  return response.json()
}
```

Store the returned account ID against the correct user in your database. Follow Mono's [official exchange-token reference](https://docs.mono.co/api/bank-data/authorisation/exchange-token) for the current response schema and production requirements.

<Warning>
  `MONO_SECRET_KEY` must never be prefixed with `NEXT_PUBLIC_`, embedded in a frontend bundle, logged, or sent to the browser.
</Warning>

## Confirm the integration

The first account-linking path is complete when:

1. `setup()` has mounted the hidden widget.
2. A user action calls `open()`.
3. `onSuccess` receives `{ code }` after linking.
4. Your backend exchanges the code.
5. Your application stores the returned Mono account ID.

## Continue

<CardGroup cols={2}>
  <Card title="Framework guides" icon="code" href="/content/sdk/connect-js/frameworks/react">
    Adapt the lifecycle to React, Angular, or Next.js.
  </Card>

  <Card title="Events" icon="bell" href="/content/sdk/connect-js/reference/events">
    Instrument the widget lifecycle without treating events as success confirmation.
  </Card>

  <Card title="Reauthorization" icon="rotate" href="/content/sdk/connect-js/usage/reauthorization">
    Reconnect a linked account with its account ID.
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/content/sdk/connect-js/usage/troubleshooting">
    Diagnose setup, key, callback, and exchange failures.
  </Card>
</CardGroup>
