For the complete documentation index, see llms.txt. This page is also available as Markdown.

SDK Reference

@health-universe/react exposes typed React Query hooks grouped by clinical domain, plus a generic escape hatch (useApiQuery / useApiMutation / api) for any scoped operation that doesn't yet have a first-class hook.

Every hook's arguments and return type are inferred from the generated client, so the bundled TypeScript declarations (@health-universe/react ships .d.ts) are the canonical source of truth — your editor's autocomplete is the fastest reference.

Org id vs workspace slug. Two different identifiers address the organization, and mixing them up is the most common mistake. Both come from useHealthUniverseAuth().organization (see Auth):

  • Org id (org_…, organization.id) — used by org-scoped hooks as a query param: usePatients({ organizationId }), useRoutines(organizationId), useOrgRoutineRuns(organizationId). (Org-scoped hooks also default to the provider's active org, so you often don't pass it.)

  • Workspace slug (e.g. acme-health, organization.slug) — used by workspace-scoped hooks as a path param: useSources(slug), useBundleDetail(slug, bundleId).

If a workspace-scoped hook returns nothing, check the slug and your org membership first.


Auth

The SDK manages Clerk internally — you never import @clerk/clerk-react. It loads Clerk's official script from Clerk's CDN at runtime (the same way @clerk/clerk-react does), so the prebuilt widgets are fully styled. Read sign-in state and the active organization, and trigger sign-in/out/org-switching, through the SDK.

import { useHealthUniverseAuth, SignedIn, SignedOut, OrganizationSwitcher, UserButton } from '@health-universe/react'

function Header() {
  const { isSignedIn, user, organization } = useHealthUniverseAuth()
  return (
    <header>
      <OrganizationSwitcher />   {/* Clerk's prebuilt widget, via clerk-js */}
      <UserButton />
    </header>
  )
}

// Gate UI on sign-in state:
<SignedIn><App /></SignedIn>
<SignedOut><SignInScreen /></SignedOut>

useHealthUniverseAuth() returns:

  • isLoaded, isSignedIn

  • user — the signed-in user (id + display fields)

  • organization — the active org as { id, slug, name } (the source of both the org id and the workspace slug above), or null

  • organizations — the user's org memberships, for a custom switcher

  • signIn(), signOut(), setActiveOrg(organizationId)

Components: <SignedIn> / <SignedOut> gate on sign-in state; <OrganizationSwitcher> / <UserButton> render Clerk's prebuilt, styled widgets (use useWorkspace().isPinned to hide the switcher in a pinned app). See Your First App for provider setup.

Locked by platform policy. These widgets are pinned to a deployed app's scope and can't be unlocked by props: <OrganizationSwitcher> is switch-only (no personal workspace, no Create/Manage organization) and <UserButton> hides "Manage account" (Sign out stays). The org slug for workspace-scoped hooks still comes from useHealthUniverseAuth().organization.slug. The hiding is a UI lock — for an airtight boundary, also disable org creation and restrict the manage/account permissions in the Clerk Dashboard.


Patients

The full set:

  • usePatients(params, options) — list / search the org's patients

  • usePatient(id) — a single patient

  • useCreatePatient(), useUpdatePatient(), useDeletePatient()

  • useUpsertPatientByExternalId() — idempotent EHR sync, keyed by your external id


Documents

The full set:

  • useDocumentSearch() — structured search

  • useSemanticDocumentSearch() — semantic search (e.g. { body: { query: 'aml relapse', threadId } })

  • useDocumentTextSearch() — text search

  • useDocumentStatus(id), useDocumentStatuses() — status by document, or by thread/patient

  • useDocumentChunks(id) — a document's extracted text, returned as ordered chunks

  • useExportDocument()

Render a document's text by sorting its chunks:


Routines & runs

The full set:

  • useRoutines(orgId), useRoutine(id) — list/read routines (name, description, steps[] pipeline, inputs[])

  • useCreateRoutine(), useUpdateRoutine(), useDeleteRoutine(), useDiscoverRoutines()

  • Routine-secret hooks

  • useTriggerRoutine() — start a run; returns the new run_id

  • useRoutineRun(runId) — a single run, with terminal-aware polling (default 3s, stops at a terminal status)

  • useRoutineRuns(routineId), useOrgRoutineRuns(orgId) — run history

  • useRetryRun(), useCreateRunThread(), useDeleteRunThread()

A run's generated documents live on each step's output_artifacts as an A2A artifact array — [{ name, parts: [{ kind: 'text', text }] }]:

Generated text often embeds citation tags like <file name="x.pdf">x.pdf</file>. react-markdown won't render raw HTML, so strip or transform those before rendering.


Sources (bundles) & run review

useSources and useBundleDetail are workspace-scoped — they take the org slug as a path param, not the org id.

A routine run carries its source bundle on trigger_context.bundle_id. To build a full run-review surface, pair:

  • useRoutineRun(id) — steps + output_artifacts (the generated documents), and

  • useBundleDetail(slug, bundleId) — the input documents + patient the run started from.

See the react-starter RunView for a worked example.


Chat threads

Navigator threads are where context documents live.

The full set: useThreads, useThread, useCreateThread, useUpdateThread, useDeleteThread.


Other clinical domains

These domains are available as hooks and/or through the escape hatch below:

  • ProvidersuseProviders, useProvider, useCreateProvider, useUpsertProviderByNpi

  • RostersuseRosters, useRoster, useRosterPatients, …

  • AppointmentsuseAppointments, …

  • ConnectorsuseEnabledConnectors

  • Clinical toolsuseAutofillForm, useExecuteTool, useGenerateFormSchema, useSuggestTools


Any endpoint, fully typed — useApiQuery / useApiMutation

Every scoped operation can be turned into a typed query or mutation without a bespoke hook. Domains that don't yet have first-class hooks (providers, rosters, appointments, clinical tools, connectors, bundles) are reachable this way today. Options and the returned data type are inferred from the operation.

api is the generated SDK for the scoped surface only. You can also grab the raw client with useHealthUniverseClient() and call api.* imperatively.


Invalidating queries & realtime

Query-key factories are exported so you can invalidate after a mutation or an out-of-band update: patientKeys, runKeys, documentKeys, sourceKeys, threadKeys, and so on.

For run progress, useRoutineRun already polls (default 3s) and stops at a terminal status. The SDK does not bundle Supabase — for sub-second updates, supply your own subscription and invalidate the relevant query (runKeys.detail(runId), patientKeys.list(...), etc.).


Scope

The client is intentionally limited to the clinical domains above (routines, documents, patients, providers, rosters, appointments, sources/bundles, chat threads, clinical tools, connectors). Admin, deployments, billing, and internal tooling are not part of this package and cannot be called through it.

Last updated

Was this helpful?