Skip to content

Upvio SDK

@upvio/sdk-node is the official server-side SDK for the Upvio API. It provides typed methods for managing patients, vitals scans, and magic link authentication.

  • Node.js 22 or later
  • ESM project ("type": "module" in package.json)
Terminal window
pnpm add @upvio/sdk-node

Create a client instance with your API key and Business ID:

import { UpvioApiClient } from '@upvio/sdk-node'
const client = new UpvioApiClient({
apiKey: process.env.UPVIO_API_KEY,
businessId: process.env.UPVIO_BUSINESS_ID,
})

Store your credentials in .env.local (and add it to .gitignore):

UPVIO_API_KEY=your-api-key
UPVIO_BUSINESS_ID=your-business-id
UPVIO_BUSINESS_ALIAS=your-business-alias
  • UPVIO_API_KEY and UPVIO_BUSINESS_ID — found on the API Keys page in Settings.
  • UPVIO_BUSINESS_ALIAS — your Business Alias, used to build scan URLs: https://{alias}.clients.upvio.com/vitals/links/{slug}.

All methods are accessed through the client.v1 namespace and return typed promises.

const { data: templates } =
await client.v1.vitals.templates.list()
for (const template of templates) {
console.log(template.name, template.metrics)
}
const { data: links } =
await client.v1.vitals.links.list({ status: 'ACTIVE' })
const { data: patient } =
await client.v1.core.patients.create({
name: 'Jane Smith',
})

By default, if a patient with the same email exists, their record is updated (upsert). Pass mode: 'create' to get a 409 error instead.

const { data: scan } =
await client.v1.vitals.scans.create({
vitalsLinkId: link.id,
patientId: patient.id,
})

You can pre-fill patient health data for more accurate risk assessments:

const { data: scan } =
await client.v1.vitals.scans.create({
vitalsLinkId: link.id,
patientId: patient.id,
inputData: {
gender: 'female',
age: 35,
height: 165,
weight: 62,
smokingStatus: 'never',
activityLevel: 'exercise20to60Mins',
},
})

Magic links authenticate a patient and redirect them to a scan page:

const alias = process.env.UPVIO_BUSINESS_ALIAS
const scanUrl =
`https://${alias}.clients.upvio.com/vitals/links/${link.slug}`
const { data: magicLink } =
await client.v1.core.patients.createMagicLink(
patient.id,
{ redirectUrl: scanUrl },
)
// Send magicLink.url to the patient
console.log(magicLink.url)
const { data: scan } =
await client.v1.vitals.scans.retrieve(scanId)
if (scan.status === 'SUCCEEDED' && scan.results) {
console.log(scan.results.metrics)
// { heartRate: 72, bloodPressureSystolic: 120, ... }
}

The SDK does not throw for API errors. Every method resolves to an object with either data or error, so check data before using it:

const { data: scan, error } =
await client.v1.vitals.scans.retrieve('invalid-id')
if (!scan) {
console.error(error?.code) // 404
console.error(error?.title) // "Vitals Scan not found"
return
}
console.log(scan.status)

The promise only rejects when the request itself fails, such as on a network error or a response that is not JSON.

See Error Handling for common error scenarios.