npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ontomorph/dtp-sdk

v0.1.4

Published

Official TypeScript SDK for the DTP digital-twin platform: connect twins via grant tokens, query systems, list and stream events, flag findings, manage API keys, and reach the HOLON clinical-knowledge API.

Readme

@ontomorph/dtp-sdk

The official TypeScript SDK for the DTP digital-twin platform. With one typed client you can connect to a patient's digital twin through a consent grant, read their health data by body system, watch for new events, flag findings back onto the twin, manage your API keys, and reach the HOLON clinical-knowledge API.

Runs on Node.js 18+, Bun, Deno, and any modern browser or edge runtime with fetch. Fully typed, with no runtime dependencies beyond the bundled HOLON client.

The wiki has the full guide: getting started, concepts, guides, use cases, API reference, and FAQ.

npm install @ontomorph/dtp-sdk
# pnpm add @ontomorph/dtp-sdk
# yarn add @ontomorph/dtp-sdk
# bun add @ontomorph/dtp-sdk

Concepts

New to the platform? These are the terms this SDK uses, and why each one exists.

Digital twin. A living model of one patient's body, assembled from their health data and organized by body system. You never touch raw records; you read and write the twin.

Body system. A physiological grouping such as cardiovascular or respiratory. Systems are how you slice a twin into the part you care about instead of pulling everything at once.

Health event. One timestamped entry on a twin: a lab result, an observation, a flag you raised. The clinical fields (the measurement code, its value, its unit, its body system) live inside the event's data object rather than at the top level, because the platform stays agnostic about which coding system you use.

Grant, and grant token. Consent, encoded. A patient issues a grant that authorizes you to reach exactly one twin, scoped to the body systems and event types they approved. The grant token is the signed proof of that consent, and it is what you pass to dtp.twins.connect(). No grant, no patient data.

DTP API key. Identifies your application to the platform. A key beginning dtp_live_ talks to production; dtp_test_ talks to the sandbox. On its own a key never unlocks patient data. It says who you are, not what you may see.

Flag. A finding you write back onto a twin as a new event, for example marking an LDL result as above target. Flagging is how your integration contributes back rather than only reading.

HOLON. The clinical-knowledge service behind the platform: drug interactions, concept lookups across SNOMED / RxNorm / LOINC, reference ranges, and phenotype similarity. The SDK exposes it under dtp.holon so one client covers both a patient's data and the knowledge to interpret it.

Quick start

import { DTP } from "@ontomorph/dtp-sdk";

const dtp = new DTP({ apiKey: process.env.DTP_API_KEY }); // dtp_live_… or dtp_test_…

// A patient issues you a grant token; connect to their twin with it.
const twin = await dtp.twins.connect(grantToken);

// Read one body system.
const cardio = await twin.systems.get("cardiovascular");
console.log(cardio.events.length, "cardiovascular events");

// Watch for new events and flag anything abnormal back onto the twin.
const stream = twin.events.stream({ system: "cardiovascular" }, (event) => {
  if (event.data.code === "LDL" && Number(event.data.value) > 130) {
    twin.flag("cardiovascular", event);
  }
});

// later…
stream.stop();

Authentication

The SDK uses two credentials for two different jobs:

| Credential | Passed as | Needed for | | --- | --- | --- | | DTP API key (dtp_live_… / dtp_test_…) | apiKey in the constructor, sent as X-DTP-API-Key | every twin-core request (twins) | | Grant token (a signed JWT the patient issues) | dtp.twins.connect(grantToken) | access to a specific twin's data |

An API key alone never reaches patient data. It identifies you. A grant token, issued by the patient through their consent flow, authorizes access to one twin, scoped to the body systems and event types they approved.

Get an API key from the developer dashboard.

Three features need extra credentials, supplied in the same constructor:

  • dtp.keys (manage your own API keys) is user-authed, so it needs a sessionToken (a Zitadel user JWT), not just the API key.
  • dtp.sandbox (mint synthetic demo grant tokens) is also user-authed, same sessionToken requirement.
  • dtp.holon (clinical knowledge) needs holonApiUrl and holonApiKey.

Configuration

new DTP({
  apiKey:       "dtp_live_…",  // required, X-DTP-API-Key on twin requests
  baseUrl:      "https://api.ontomorph.com",  // twin-core (default shown)
  identityUrl:  "https://api.ontomorph.com",  // identity-consent, for dtp.keys (default shown)
  sandboxUrl:   "https://sandbox-api.ontomorph.com", // sandbox service, for dtp.sandbox (default shown)
  sessionToken: "<zitadel user jwt>",          // required only for dtp.keys.* and dtp.sandbox.*
  holonApiUrl:  "https://holon-api.ontomorph.com", // required only for dtp.holon
  holonApiKey:  "holon_…",                      // required only for dtp.holon
  timeout:      30_000,                          // per-request ms (default)
});

Only apiKey is required. Everything else has a sensible default or is only needed for the feature that uses it.

API

dtp.twins

connect(grantToken) decodes the grant locally and returns a Twin. It does not hit the network (the token is verified server-side on the first data request), so it returns fast, and the twin.grant claims (grantId, twinId, systems, eventTypes) are available right away.

const twin = await dtp.twins.connect(grantToken);
twin.grant.twinId;  // the twin this grant authorizes
twin.grant.systems; // e.g. ["cardiovascular"], or null for all

twin.systems

const view = await twin.systems.get("cardiovascular");
// SystemView: { system, twinId, events: HealthEvent[] }

A SystemView is built from the twin's grant-scoped events filtered by event.data.system. Clinical fields (code, value, unit, system) live inside each event's data object, not at the top level.

twin.events

// One-shot list (paginated).
const events = await twin.events.list({ system: "cardiovascular", limit: 50 });

// Continuous watch. Returns a handle; call stop() to end it.
const handle = twin.events.stream(
  { system: "cardiovascular", intervalMs: 5_000 },
  (event) => console.log("new event", event.id),
);
handle.stop();

How stream works: twin-core has no grant-scoped push stream, so stream polls list on an interval (every 5s by default, set by intervalMs) and emits only events it has not seen before. For high-frequency needs, poll list yourself on your own schedule.

twin.flag

Write a flag event back onto the twin. Any HealthEvent satisfies FlagInput, so a streamed event can be forwarded straight through:

await twin.flag("cardiovascular", {
  code: "LDL",
  value: 190,
  title: "LDL above target",
  description: "Consider statin review",
});

The grant must permit the flag's eventType, which defaults to "clinical_note".

twin.simulate

Run a what-if trajectory simulation. Baseline values (e.g. starting LDL for "ldl_trajectory") auto-derive from the twin's own recent lab results unless you pass them in params:

const result = await twin.simulate("ldl_trajectory", {});
console.log(result.scalarOutputs, result.disclaimer);

Against a real twin this polls until the queued job completes (up to 2 minutes) and returns AI narration plus a 3D animation; against the sandbox host it resolves immediately with narration/animation both null. Only "ldl_trajectory" and "hba1c_trajectory" are implemented on the sandbox host. Throws DTPApiError (code TIMEOUT or the job's real failure reason) if the run doesn't succeed.

dtp.sandbox (try it with synthetic data)

Requires sessionToken in the constructor. Mints fresh grant tokens for a standing cohort of synthetic demo twins, physically isolated from real patient data — pair with a dtp_test_… API key to build against the platform before you have a real patient's grant.

const [grant] = await dtp.sandbox.grants();
const twin = await dtp.twins.connect(grant.grantToken);
const events = await twin.events.list();

Each token is valid for grant.expiresIn seconds; call dtp.sandbox.grants() again to mint a fresh one once it expires.

dtp.keys (manage your API keys)

Requires sessionToken in the constructor.

const keys = await dtp.keys.list();
const created = await dtp.keys.create({
  name: "CI pipeline",
  keyType: "personal",        // personal | org | device | research
  scopes: ["twins:read"],
  environment: "live",        // live | test
});
console.log(created.key);      // the raw key, shown exactly once
await dtp.keys.revoke(created.id);

dtp.holon (clinical knowledge)

Requires holonApiUrl and holonApiKey. Returns a configured @ontomorph/holon-client:

const results = await dtp.holon.concepts.search("atorvastatin");
const drugA = results.hits[0].conceptId;
// check a pair of drug concept ids for a known interaction
const interaction = await dtp.holon.interactions.check(drugA, otherDrugId);

See the @ontomorph/holon-client docs for the full clinical-knowledge surface.

Error handling

Every failed request throws a DTPApiError with a machine-readable code. Configuration mistakes throw DTPConfigError.

import { DTP, DTPApiError, DTPConfigError, DTPErrorCode } from "@ontomorph/dtp-sdk";

try {
  const twin = await dtp.twins.connect(grantToken);
  await twin.systems.get("cardiovascular");
} catch (err) {
  if (err instanceof DTPApiError) {
    console.error(err.code, err.details.status, err.message); // e.g. FORBIDDEN 403 …
    if (err.code === DTPErrorCode.UNAUTHORIZED) refreshCredentials();
  } else if (err instanceof DTPConfigError) {
    console.error("SDK misconfigured:", err.message);
  }
}

err.code is one of UNAUTHORIZED, FORBIDDEN, NOT_FOUND, VALIDATION_ERROR, SCOPE_DENIED, RATE_LIMITED, INTERNAL_ERROR, NETWORK_ERROR, or TIMEOUT. err.details carries { status, body }, where status is 0 for transport-level failures such as a network drop or timeout.

Helpers

The SDK exports a few pure utilities it uses internally, in case they are useful to you:

  • decodeGrantToken(token) reads grant claims without verifying (client-side only).
  • filterBySystem(events, system) filters a HealthEvent[] by data.system.
  • diffNewEvents(events, seen) is the set difference the stream loop uses.

TypeScript

Every public shape is exported: DTPConfig, HealthEvent, SystemView, EventFilter, StreamOptions, StreamHandle, FlagInput, GrantClaims, ApiKeyRecord, CreateApiKeyInput, CreateApiKeyResult, SandboxDemoGrant, and more. Import them directly:

import type { HealthEvent, SystemView, GrantClaims } from "@ontomorph/dtp-sdk";

Related packages

Documentation and support

License

UNLICENSED. © OntoMorph. Usage is governed by your OntoMorph platform agreement.