# Vault JS

Add `@apideck/vault-js` to any web app, pass it a Vault session token, then call `ApideckVault.open({ token })`
to launch a modal that lets your users authorize connectors and manage their integration settings, with
Apideck storing the credentials securely on their behalf. It's framework-agnostic vanilla JavaScript. Three
steps get it running:

- [Step 1: Setup Apideck](#step-1-setup-apideck)
- [Step 2: Create a session](#step-2-create-a-session)
- [Step 3: Add Vault JS](#step-3-add-vault-js)

## Vault Links

Vault Links let a customer authorize a connection in Hosted Vault without embedding a connection screen in your product. Choose the hosted flow when the person setting up the integration is different from the person who can authorize the account.

- **Enterprise onboarding:** an implementation team prepares the consumer and connection, then shares the link privately with the customer's authorized finance or IT administrator.
- **Agent workflows:** your backend creates a consumer-scoped session and presents its hosted link to the user. The user completes authorization in Vault; your backend checks the connection before the agent resumes API calls. The agent does not need the user's provider password or OAuth credentials.
- **Embedded onboarding:** use Vault JS below when customers should manage connections directly inside your application.

### Create and hand off a link

1. Choose the consumer ID for the customer account. Keep this same ID when making subsequent Unified API calls.
2. Create a session on your backend using [Step 2](#step-2-create-a-session). In the REST response, `data.session_uri` is the hosted URL; `data.session_token` is used by embedded Vault.
3. Present the hosted URL only to the authorized customer. Alternatively, create a **Vault Magic Link** from the consumer in the dashboard, as described in the [dashboard walkthrough](https://help.apideck.com/en/articles/4233154).
4. After authorization, check the [connection state](/guides/connection-states) and required settings. A user opening the link is not proof that authorization completed. Only then continue the integration or agent task.
5. If the session expires before completion, create a fresh session for the same consumer.

Treat the hosted link as a credential. Keep it out of public tickets, analytics, and agent conversation logs. A Vault session authorizes connection setup; it does not replace your application's authorization rules for an agent that reads or writes customer data.

## Step 1: Setup Apideck

### Create an account

If you haven't already, head over to our [Signup page](https://www.apideck.com/signup?products=unify&source=docs-vault-js) and create an account. Create your application in the Apideck dashboard.

### Enable Unified APIs and connectors

Open **Configuration** in the [Apideck dashboard](https://platform.apideck.com) in the Apideck dashboard. Choose one or more Unified APIs to enable. You'll see a list of the available connectors for each Unified API. Choose a couple of connectors to enable. The Unified APIs and connectors you select become available to your users in [Vault](https://developers.apideck.com/apis/vault/reference).

### Get your API key and Application ID

Go to the [API Keys](https://platform.apideck.com/configuration/api-keys) page in the Apideck dashboard. Copy your application ID and API key.
If your API key ever gets compromised, you can regenerate it on this page.

Keep both values on your backend. Your browser receives a short-lived, consumer-scoped session token, never your Apideck API key.

## Step 2: Create a session

Vault lets your users (called consumers in Apideck) easily connect and configure integrations. You can create a consumer through a Vault session through the following endpoint [Create session](/apis/vault/reference/sessions#sessionsCreate).

Most of the time, this is an ID of your internal data model that represents a user or account in your system. E.g., account:12345. If the consumer doesn't exist yet, Vault will upsert a consumer based on your ID.

> **Note 🚨**
>
> Create sessions on your backend to keep the Apideck API key out of the browser. Return only the scoped session credentials to the authorized customer.

Use the API call below to create a session for a consumer. This will return a Vault URL that you forward to a consumer to connect integrations.

```sh meta=terminal
curl --request POST \
  --url 'https://unify.apideck.com/vault/sessions' \
  --header 'Authorization: Bearer {API_KEY}' \
  --header 'x-apideck-app-id: {APP_ID}' \
  --header 'x-apideck-consumer-id: {CONSUMER_ID}' \
  --header 'Content-Type: application/json' \
  --data '{}'
```

You can also use one of our [SDKs](/sdks/node) to create a session, like for example the Node SDK:

```sh meta=terminal
npm install @apideck/unify@0.52.2
```

Call this function from an authenticated server endpoint. Resolve `consumerId` from the signed-in customer's tenant in your own database; do not trust an arbitrary consumer ID submitted by the browser. Authorize the user to manage that tenant's integrations before creating a session.

```ts meta=server/create-vault-session.ts
import { Apideck } from '@apideck/unify'

export async function createVaultSession(consumerId: string) {
  const apiKey = process.env.API_KEY
  const appId = process.env.APP_ID
  if (!apiKey || !appId || !consumerId) throw new Error('Missing Vault configuration')

  const apideck = new Apideck({ apiKey, appId, consumerId })
  const result = await apideck.vault.sessions.create({
    session: { settings: { unifiedApis: ['accounting'] } }
  })
  const session = result.createSessionResponse?.data
  if (!session?.sessionToken) throw new Error('Vault did not return a session token')
  return { token: session.sessionToken, sessionUri: session.sessionUri }
}
```

The TypeScript SDK uses `sessionToken` and `sessionUri`; the REST response uses `session_token` and `session_uri` inside `data`. Pass the token as Vault JS's `token` option. Alternatively, redirect the customer to the hosted Vault URL. Treat either value as a credential: do not put it in analytics or application logs.

Before you hand this session URL to a consumer, make sure your own product has already told them what they're connecting and why — see [End-user consent](/guides/end-user-consent) for what to show and what to put in your terms.

### Customizing the session

When creating a session, you can customize the Vault experience by providing various settings, for example:

```ts
const session = {
  settings: {
    unifiedApis: ['accounting'],
    sessionLength: '1h',
    hideResourceSettings: false,
    hideGuides: false
  }
}
```

Pass this object as `session` to `apideck.vault.sessions.create`. SDK settings use camelCase; REST settings use snake_case. Keep setup guides and required resource settings visible while customers configure their connection. See [session settings](/apis/vault/reference/sessions#sessionsCreate) for the complete contract.

## Step 3: Add Vault JS

Install the package, then open it with the session token from Step 2.

### Installation

#### Package

```sh
npm install @apideck/vault-js@1.8.1
```

#### Script

If you don't want to set up a build environment, you can get `@apideck/vault-js` from a CDN like unpkg.com or jsdelivr.net and it will be globally available through the `window.ApideckVault` object.

```html
<script src="https://cdn.jsdelivr.net/npm/@apideck/vault-js@1.8.1"></script>
```

### Usage

Pass the JWT you got from the Vault session to `@apideck/vault-js`:

```js
import { ApideckVault } from '@apideck/vault-js'

ApideckVault.open({
  token: 'REPLACE_WITH_SESSION_TOKEN'
})
```

If you want to only show integrations for a single Unified API, you can do that by passing the `unifiedApi` option. If you want to open Vault for only a single integration, you can provide the `serviceId` option.

```js
import { ApideckVault } from '@apideck/vault-js'

ApideckVault.open({
  token: 'REPLACE_WITH_SESSION_TOKEN',
  unifiedApi: 'accounting',
  serviceId: 'quickbooks'
})
```

If you want to get notified when the modal opens and closes, you can provide the `onReady` and `onClose` options.

```js
import { ApideckVault } from '@apideck/vault-js'

ApideckVault.open({
  token: 'REPLACE_WITH_SESSION_TOKEN',
  onClose: () => {
    console.log('closed!')
  },
  onReady: () => {
    console.log('ready!')
  }
})
```

If you want to open a specific view you can pass the `initialView` prop. The available views are `settings`, `configurable-resources`, and `custom-mapping`.

```js
import { ApideckVault } from '@apideck/vault-js'

ApideckVault.open({
  token: 'REPLACE_WITH_SESSION_TOKEN',
  unifiedApi: 'accounting',
  serviceId: 'quickbooks',
  initialView: 'custom-mapping'
})
```

You can also close the modal programmatically by calling `ApideckVault.close()`.

If you want to open Vault in a specific language you can add the `locale` prop. The available locales are `en` (default), `nl`, `de`, `fr`, and `es`.

```js
import { ApideckVault } from '@apideck/vault-js'

ApideckVault.open({
  token: 'REPLACE_WITH_SESSION_TOKEN',
  locale: 'nl'
})
```

If you want to show a language switch at the bottom of the modal you can add the `showLanguageSwitch` prop.

```js
import { ApideckVault } from '@apideck/vault-js'

ApideckVault.open({
  token: 'REPLACE_WITH_SESSION_TOKEN',
  showLanguageSwitch: true
})
```

If you want to show a logo on top of the modal, you can set the `logo` property on the `theme` object you can provide through the session. [View Vault API documentation](https://developers.apideck.com/apis/vault/reference#operation/sessionsCreate).

### Verify the connection

Closing the modal does not mean authorization succeeded. Use `onConnectionChange` to refresh your app's connection status, then check the connection on your backend through [Get connection](/apis/vault/reference/connections#connectionsOne). When the connection is callable, make a read-only Accounting request with the same consumer and service IDs. Inspect [Logs](/logs) if it fails.

Use [Vault connection webhooks](/guides/webhooks#vault-connection-events-and-their-payloads) to keep status current after the customer leaves your app. Explain [end-user consent](/guides/end-user-consent) before opening Vault.

### Properties

| Property           | Type                             | Required | Default | Description                                                                                                                                      |
| ------------------ | -------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| token              | string                           | true     | -       | The JSON Web Token returned from the [Create Session API](/apis/vault/reference/sessions#sessionsCreate)                |
| showAttribution    | boolean                          | false    | true    | Show "Powered by Apideck" in the backdrop of the modal backdrop                                                                                  |
| onReady            | () => void                       | false    | -       | Function that gets called when the modal is opened                                                                                               |
| onClose            | () => void                       | false    | -       | Function that gets called when the modal is closed                                                                                               |
| onConnectionChange | (connection: Connection) => void | false    | -       | Function that gets called when the user updates a connection. This can be linking their account, filling out settings or adding a new connection |
| onConnectionDelete | (connection: Connection) => void | false    | -       | Function that gets called when the user deletes a connection                                                                                     |
| unifiedApi         | string                           | false    | -       | When unifiedApi is provided it will only show integrations from that API.                                                                        |
| serviceId          | string                           | false    | -       | When unifiedApi and serviceId are provided Vault opens a single integration                                                                      |
| showConsumer       | boolean                          | false    | false   | If true it shows the current consumer metadata at the bottom of the modal                                                                        |
| showButtonLayout   | boolean                          | false    | false   | Use button layout instead of dropdown menu in TopBar for connection actions                                                                      |
| initialView        | ConnectionViewType               | false    | -       | Open Vault in a specific view for a connection session                                                                                           |
| locale             | string                           | false    | "en"    | Open Vault in a specific language: "en", "nl", "de", "fr" or "es"                                                                                |
| showLanguageSwitch | boolean                          | false    | false   | Show language switch at bottom                                                                                                                   |

Review [Zero Data Retention](/guides/security-and-data-handling#zero-data-retention-and-its-boundaries) for the distinction between business records passing through the API and connection credentials stored by Vault.

### Demo

See a working demo [here](https://vault-demo.apideck.com/)

## Frequently asked questions

### Should I use a Vault session token or my API key in the browser?

Use the short-lived Vault session token in the browser. Create the session on your backend with your Apideck API key, and resolve the consumer from the authenticated customer. Never send the API key to frontend application code. See [Create a session](#step-2-create-a-session).

### Can a customer connect without an embedded Vault modal?

Yes. Send the customer to the hosted URL returned as `data.session_uri` in the REST session response. Embedded Vault instead uses `data.session_token`. [Vault Links](#vault-links) are useful when a finance or IT administrator needs to authorize the account; treat both the link and token as credentials.

### Does closing Vault mean the connection is ready for API calls?

No. Check that authorization and required connector settings are complete, then make a small read using the same consumer and connector. A UI callback alone does not verify the requested operation. Follow [Verify the connection](#verify-the-connection).

### Should I create a new consumer for every session?

No. Reuse the customer’s stable consumer ID when creating another session. A new session lets that customer manage the same integration context; a different consumer identifies a different customer scope. See [consumer setup](/get-started#step-4-create-a-consumer).
