Getting Started

Initialization

Open in Claude

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

OptionTypeDefaultDescription
accessTokenstring—OAuth access token from the token exchange. If omitted, the SDK looks for a token_endpoint query parameter in the page URL.
idTokenstring—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.
debugbooleanfalseEnable debug logging to the browser console
handshakeTimeoutnumber10000Timeout for the initial extension handshake, in ms. A same-context postMessage round-trip — keep it short.
requestTimeoutnumber40000Timeout for individual SDK request/response calls, in ms. Must cover the slowest backend-executed catalog operation.
timeoutnumber—Deprecated. Use handshakeTimeout and requestTimeout. When set, both inherit from it for backwards compatibility.

How It Works

  1. The SDK loads the core library from the Vim CDN (a small script — not bundled in your app)
  2. It establishes a MessageChannel with the Vim Connect Chrome extension
  3. It authenticates using the provided accessToken
  4. Once connected, it returns a fully typed VimSDK instance
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.

FieldTypeDescription
versionstringExtension version
apiVersionstringSDK API version
supportedEventsEventManifestItem[]Available workflow events and their entities
supportedContextsContextManifestItem[]Available context subscriptions
supportedEntitiesEntityManifestItem[]Available entity types and their fields
featuresstring[]Enabled feature flags
operationsOperationManifestEntry[]API catalog operations with availability info
contextWritebackRecord<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}`);
}
FieldTypeDescription
sessionIdstringStable for one app launch. Useful for grouping logs from a single session
deviceIdstringPersistent per browser install, across restarts
userIdstringThe 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
ehrTypestringThe 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.

On this page