Skip to content
Fatunmbi Daniel edited this page Jul 19, 2026 · 1 revision

FAQ

What is the authentication model?

Two credentials for two jobs. A DTP API key identifies your application on every twin-core request. A grant token, issued by the patient, authorizes access to one specific twin. You need both to read patient data. See Concepts.

Why is an API key not enough to read patient data?

An API key says who you are, not what you may see. Patient data is gated by consent, so you also need a grant token that the patient issued for their twin, scoped to the systems and event types they approved.

What is a grant token?

A signed JWT the patient issues through their consent flow. You pass it to dtp.twins.connect(grantToken). It carries the grant claims (grantId, twinId, systems, eventTypes) and authorizes exactly one twin. No grant, no patient data.

Does stream use websockets?

No. 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. See Guides.

Which runtimes are supported?

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

How does dtp.holon relate to @ontomorph/holon-client?

dtp.holon returns a configured @ontomorph/holon-client. Set holonApiUrl and holonApiKey in the constructor, and the SDK wires up the client for you, so one DTP client covers both twin data and clinical knowledge. See the @ontomorph/holon-client docs for its full surface.

How do I handle errors?

Every failed request throws a DTPApiError with a machine-readable code and details of { status, body }. Configuration mistakes throw DTPConfigError. Branch on err.code against DTPErrorCode. details.status is 0 for transport-level failures such as a network drop or timeout. See API-Reference.

// error-handling.ts
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);
    if (err.code === DTPErrorCode.UNAUTHORIZED) refreshCredentials();
  } else if (err instanceof DTPConfigError) {
    console.error("SDK misconfigured:", err.message);
  }
}

Are TypeScript types included?

Yes. Every public shape is exported, including DTPConfig, HealthEvent, SystemView, EventFilter, StreamOptions, StreamHandle, FlagInput, GrantClaims, ApiKeyRecord, CreateApiKeyInput, and CreateApiKeyResult. Import them with import type.

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

What is the difference between sandbox and live keys?

A key beginning dtp_live_ talks to production; dtp_test_ talks to the sandbox. Same code, different environment. Use the sandbox for development and tests, live for real patient data.

Do dtp.keys and dtp.holon need extra credentials?

Yes. dtp.keys is user-authed and needs a sessionToken (a Zitadel user JWT) in the constructor. dtp.holon needs holonApiUrl and holonApiKey. The base dtp.twins surface needs only the API key plus a grant token.

Related: Getting-Started, Concepts, API-Reference.