Versa Link Integration Guide
Versa Link is the client-side component that your users will interact with in order to link their accounts to your app. It handles all aspects of the account linking experience.

Versa Link is one method of customer registration, in which most of the work is handled via the embeddable widget. Alternatively, you are welcome to implement your own customer registration via the Versa API.
IMPORTANT
The only way to support OAuth-based connections (including QuickBooks and Xero) is via Versa Link. The customer registration API does not support OAuth connections. Versa Link is the best way to ensure the broadest compatibility.
Quick Start
You'll need to make an account at https://app.versa.org and issue yourself test credentials.
Installation
Drop the script tag into your HTML to include the Versa Link widget. You'll need to configure your CSP to allow the https://cdn.versa.org source.
<script src="https://cdn.versa.org/link/stable/versa-link.iife.js"></script>
Generate a Link Token
Before you initialize Versa Link, use your server-side credentials to acquire a short-lived token to pass to the client (tokens expire after 10 minutes). In production, you will need to create a secure endpoint on your server that generates this token and returns it to your client application on behalf of the logged-in customer.
curl -X POST https://registry.versa.org/link_token \
-H "Authorization: Basic {CLIENT_ID}:{CLIENT_SECRET}" \
-H "Content-Type: application/json" \
-d '{
"handles": {
"customer_email_domain": "acme.co",
"merchant_group_code": "CORPORATE_DISCOUNT_CODE_XYZ"
}
}'
This will return a response object including the following fields:
{
"token": "link_test_wnYq4f2YjWsvHq4ffI2FYydOMQjMmJVpadUFlBWd",
"mode": "test",
"expired": 1754020800
}
Configuration
Call VersaLink.initialize() to configure the widget with the response from the /link_token endpoint above. You must include a valid handles object for the current customer.
await VersaLink.initialize({
linkToken: data.token,
handles: {
customer_email_domain: "acme.co",
merchant_group_code: "CORPORATE_DISCOUNT_CODE_XYZ",
},
onSuccess: (result) => {
// callback with the list of active connections for the provided customer handles
console.log(
"Versa Link success:",
result.connections.map((org) => org.name).join(", ")
);
},
onExit: () => {
console.log("User exited Versa Link");
},
});
Theming and Advanced Configuration Options
The following fields are optional:
| Field | Type | Description |
|---|---|---|
viewMode | enum | One of modal, inline, or dropdown. Defaults to modal. See below for a comparison of the modal and inline themes. |
whitelistOrgs | array | An explicit list of integrations to offer. If not provided, the default set of integrations will be offered. |

Launch the Widget
Once initialized, you can launch the Versa Link widget by calling the open method.
VersaLink.open();