Initialization
Initialize the SDK and connect to the Vim extension
initVimSDK
Initialize the SDK and establish a connection with the Vim Connect Chrome extension.
import { initVimSDK } from '@vimconnect/app-sdk';
const sdk = await initVimSDK({
accessToken: token, // from OAuth token exchange
debug: true,
});Options
| Option | Type | Default | Description |
|---|---|---|---|
accessToken | string | — | OAuth access token from the token exchange. If omitted, the SDK looks for a token_endpoint query parameter in the page URL. |
idToken | string | — | Vim-issued OIDC ID token. Supply this alongside accessToken so getIdToken() can resolve — the token-endpoint flow captures it automatically, but a Worker App has no page URL to harvest one from. Ignored on the token-endpoint flow. |
debug | boolean | false | Enable debug logging to the browser console |
handshakeTimeout | number | 10000 | Timeout for the initial extension handshake, in ms. A same-context postMessage round-trip — keep it short. |
requestTimeout | number | 40000 | Timeout for individual SDK request/response calls, in ms. Must cover the slowest backend-executed catalog operation. |
timeout | number | — | Deprecated. Use handshakeTimeout and requestTimeout. When set, both inherit from it for backwards compatibility. |
How It Works
- The SDK loads the core library from the Vim CDN (a small script — not bundled in your app)
- It establishes a
MessageChannelwith the Vim Connect Chrome extension - It authenticates using the provided
accessToken - Once connected, it returns a fully typed
VimSDKinstance
try {
const sdk = await initVimSDK({ accessToken, debug: true });
// SDK is connected and ready
} catch (error) {
// Connection failed — extension not installed, wrong EHR, or timeout
console.error('SDK initialization failed:', error);
}Loading without a bundler
@vimconnect/app-sdk is a thin loader — it injects the core runtime from Vim's CDN at
https://core-sdk.getvim.ai/index.js. That bundle is an IIFE that also assigns a global, so an app
with no build step can load it directly:
<script src="https://core-sdk.getvim.ai/index.js"></script>
<script>
(async () => {
const sdk = await window.VimSDK.init({ accessToken });
// ... use sdk
})();
</script>window.VimSDK exposes init, get, initWorker and getWorker — the same four entry points the
npm package re-exports as initVimSDK, getVimSDK, initWorkerVimSDK and getWorkerVimSDK. It also
exposes isSDKError, the script-tag counterpart of the package's isSDKError (see
Error Handling). Call it as window.VimSDK.isSDKError?.(err): a page can be
served a core from before it existed.
Prefer the package
The npm package is the supported path: you get the TypeScript types and the Zod schemas, and the version you install is the contract you code against.
Note that neither path pins the core runtime — the package is a loader, so it fetches the same rolling CDN bundle the script tag does. The script tag additionally gives up the types, has no version in the URL and no Subresource Integrity hash, so reach for it only when you genuinely have no build step.
getVimSDK
Retrieve the current SDK instance without re-initializing. Returns null if not initialized.
import { getVimSDK } from '@vimconnect/app-sdk';
const sdk = getVimSDK();
if (sdk) {
// SDK is initialized and ready
}Useful in utility functions or components that don't have direct access to the SDK instance from initialization.
waitUntilReady
Wait until the SDK has fully connected to the extension and received the initial manifest.
const sdk = await initVimSDK({ accessToken });
try {
await sdk.ehr.waitUntilReady({ timeout: 5000 });
// SDK is fully ready — manifest, events, and context are available
} catch (error) {
console.error('SDK not ready:', error);
}In most cases, initVimSDK() already waits for the connection. Use waitUntilReady() when you need to ensure the manifest and capabilities are loaded before proceeding.
getManifest
Retrieve the SDK manifest describing available events, entities, and capabilities for the current EHR system.
const manifest = sdk.ehr.getManifest();
console.log('Supported events:', manifest.supportedEvents.map(e => e.id));
console.log('Supported contexts:', manifest.supportedContexts.map(c => c.contextKey));
console.log('Writable entities:', Object.keys(manifest.contextWriteback ?? {}));The manifest is system-specific — different EHRs support different events, entities, and fields.
| Field | Type | Description |
|---|---|---|
version | string | Extension version |
apiVersion | string | SDK API version |
supportedEvents | EventManifestItem[] | Available workflow events and their entities |
supportedContexts | ContextManifestItem[] | Available context subscriptions |
supportedEntities | EntityManifestItem[] | Available entity types and their fields |
features | string[] | Enabled feature flags |
operations | OperationManifestEntry[] | API catalog operations with availability info |
contextWriteback | Record<string, ...> | Writeback capabilities per entity |
Using the Manifest for Feature Detection
const manifest = sdk.ehr.getManifest();
// Check if a specific event is supported
const hasEncounterOpen = manifest.supportedEvents.some(e => e.id === 'encounter_open');
// Check if writeback is available for an entity
const canWriteEncounter = manifest.contextWriteback?.encounter?.update != null;
// List writable fields
const writableFields = manifest.contextWriteback?.encounter?.update?.updatableFields ?? [];Session Context
sdk.sessionContext identifies the Vim session your app is running in. The five data fields are
seeded synchronously from the VIM_SDK_INIT handshake — no fetch, no await. getIdToken() is the
exception: it returns a Promise.
const sdk = await initVimSDK({ accessToken });
if (sdk.sessionContext) {
const { sessionId, deviceId, userId, account, ehrType } = sdk.sessionContext;
console.log(`${userId} @ ${account.name} on ${ehrType}`);
}| Field | Type | Description |
|---|---|---|
sessionId | string | Stable for one app launch. Useful for grouping logs from a single session |
deviceId | string | Persistent per browser install, across restarts |
userId | string | The Vim user's UUID. For seamless / system-session users this is the provisioned Vim user id — it is not the EHR username |
account | { id, name } | The Vim account the user is operating under — what the legacy SDK called the organization |
ehrType | string | The EHR the app is running on top of, e.g. 'athena' |
getIdToken() | () => Promise<{ idToken }> | The Vim-issued ID token. Resolves when the SDK holds one — either captured from your token endpoint, or supplied as initVimSDK({ accessToken, idToken }). Rejects with ID_TOKEN_UNAVAILABLE if you passed accessToken alone. See Authentication |
sessionContext can be null
sdk.sessionContext is typed SessionContext | null. It is null until the extension has handed off
the session seed, and on older extension builds that do not send one. Always guard before reading
it:
const accountId = sdk.sessionContext?.account.id;Worker Apps get the same object at worker.sessionContext, with the same shape and the same null
guard. A worker has no page URL to harvest a token_endpoint from, so to make getIdToken() work
there, pass the token through at init: initWorkerVimSDK({ accessToken, idToken }).
What it identifies, and what it proves
sessionContext identifies the session, not the person. It carries no name, email, NPI or role. If
your app needs the provider's identity, exchange the ID token with your own backend — see
Token Lifecycle.
The data fields are not proof of anything
sessionId, deviceId, userId, account and ehrType are plain values seeded into page
JavaScript. Anything running in your app frame can change them, so never use userId or
account.id as a tenant or user key on your own backend. Send the ID token instead and let your
server derive identity from the verified JWT — that is the only value here a server can trust. See
Authentication for the exchange, and verify the token's signature, issuer,
audience and expiry server-side before acting on it.
Worker SDK Initialization
For headless background apps, use the Worker SDK:
import { initWorkerVimSDK, getWorkerVimSDK } from '@vimconnect/app-sdk';
const worker = await initWorkerVimSDK({ debug: true });
// Or retrieve later
const worker = getWorkerVimSDK();See Worker Apps for the full Worker SDK API.