@radscribe/sdk
v0.3.14
Published
RadScribe partner TypeScript SDK — Phase 1 (/api) + Phase 2 (/v1 API keys)
Maintainers
Readme
@radscribe/sdk
Official TypeScript SDK for the RadScribe partner platform (/v1).
Build your own UI or BFF and call SDK methods with an org API key — no raw HTTP URLs required.
Auth: rk_test_… (demo / local) or rk_live_… (live / prod) — server / BFF only, never in the browser
Requirements: Node.js 18+ (or any modern runtime with fetch / WebSocket)
| API host | Key |
|----------|-----|
| Demo (APP_ENV=demo, e.g. demo-radscribe-api.mightium.ai) | rk_test_… only |
| Live / prod / staging | rk_live_… only |
| Local / test | either |
The SDK throws API_KEY_HOST_MISMATCH at client construction if the key prefix does not match the apiUrl host (same rules as the API). The server still rejects mismatches with 401 if you bypass the client check.
Override ambiguous hosts with RADSCRIBE_HOST_ENV=demo|live|local. Escape hatch: skipKeyHostCheck: true (server still enforces).
Install
npm i @radscribe/sdkyarn add @radscribe/sdk
pnpm add @radscribe/sdkimport { RadScribeClient, isRadScribeError } from "@radscribe/sdk";Quickstart
Mint a key in Clinical Studio → API Keys.
# Demo
export RADSCRIBE_API_KEY="rk_test_…"
export RADSCRIBE_BASE_URL="https://demo-radscribe-api.mightium.ai"
# Production
# export RADSCRIBE_API_KEY="rk_live_…"
# export RADSCRIBE_BASE_URL="https://radscribe-api.mightium.ai"
# Local:
# export RADSCRIBE_BASE_URL="http://127.0.0.1:8000"import { RadScribeClient } from "@radscribe/sdk";
// API URL is required — pass it every time (no silent internal default):
const client = RadScribeClient.withApiKey("rk_test_…", {
apiUrl: "https://demo-radscribe-api.mightium.ai",
});
// Production:
const live = RadScribeClient.withApiKey("rk_live_…", {
apiUrl: "https://radscribe-api.mightium.ai",
});
// Local:
const local = RadScribeClient.withApiKey("rk_test_…", {
apiUrl: "http://127.0.0.1:8000",
});
// Env: both required
// export RADSCRIBE_API_KEY="rk_test_…"
// export RADSCRIBE_BASE_URL="https://radscribe-api.mightium.ai"
const fromEnv = RadScribeClient.fromEnv();
const draft = await client.reports.create({});
await client.reports.update(draft.id, {
firstName: "Ada",
lastName: "Lovelace",
gender: "female",
mobile: "9999999999",
templateId: "TPLSDKCHEST001",
transcript: "Chest radiograph. Lungs are clear.",
});
const job = await client.reports.generate({ reportId: draft.id });
await client.jobs.wait(job.id);apiUrl (or baseUrl / RADSCRIBE_BASE_URL) is required.
Key-only init throws MISSING_API_URL. Production host: https://radscribe-api.mightium.ai.
Auth
import { RadScribeClient } from "@radscribe/sdk";
const client = RadScribeClient.withApiKey(process.env.RADSCRIBE_API_KEY!, {
apiUrl: process.env.RADSCRIBE_BASE_URL ?? "https://radscribe-api.mightium.ai",
});Org login (still requires rk_*)
const session = await client.auth.login({
email: "[email protected]",
password: "secret",
});
// session.accessToken — user JWT for your app; /v1 routes still use the API keyOrganization & invites
Requires scopes org:read / org:admin on the API key.
const org = await client.organization.get();
const members = await client.organization.listMembers();
const invite = await client.organization.inviteMember({
email: "[email protected]",
orgRole: "member",
// Optional: rewrite invite link to your app (or localhost)
inviteBaseUrl: "https://partner.example.com",
// inviteBaseUrl: "http://localhost:3000",
});
// Share invite.inviteUrl with the invitee (or email it yourself).
// Paths stay /accept-invite?token=… or /signup?email=…&invite_token=…inviteBaseUrl is handled in the SDK only — it is not sent to the API. Host /accept-invite and /signup on that origin (same query params), or point it at Clinical Studio.
Workflow (step machine)
awaiting_patient → awaiting_transcript → awaiting_finalize → completedRun create → set patient → transcribe → finalize once per session. Replaying a step on a finished workflow returns 409 workflow_step_conflict.
const wf = await client.workflows.create();
await client.workflows.setPatient(wf.id, { patientId: "1000000000000001" });
await client.workflows.transcribeAndCorrect(wf.id, {
rawTranscript: "lungs clear",
});
await client.workflows.finalize(wf.id, "TPLSDKCHEST001");Patients
const patients = await client.patients.list({ q: "", limit: 200, offset: 0 });
const page = await client.patients.listPage({ q: "Ada", limit: 50, offset: 0 });
const one = await client.patients.get(patients[0]!.uhid);Live dictation
Live voice → text via client.dictation.connect (partner API key → wss://…/v1/transcribe/live). Send PCM 16-bit little-endian, 16 kHz, mono after onReady.
When ASR credits run out, onError receives the server message (close 4002). Other failures: ask the user to retry (close 1011).
- SDK:
docs/scalar/reference/dictation.md - API (WSS):
docs/scalar/api/live-transcription.md - Postman:
docs/sdk/radscribe-partner-live-websocket.postman_collection.json
import { RadScribeClient } from "@radscribe/sdk";
const client = RadScribeClient.fromEnv();
// or: RadScribeClient.withApiKey(process.env.RADSCRIBE_API_KEY!, { baseUrl })
const session = await client.dictation.connect({
onReady: () => console.log("ready — start sending PCM"),
onTranscript: ({ transcript, isFinal }) => {
console.log(isFinal ? "FINAL:" : "partial:", transcript);
},
onError: (msg) => console.error(msg),
onClose: () => console.log("closed"),
});
session.sendAudio(pcmChunk); // ArrayBuffer | TypedArray | Blob
session.close();Errors
import { isRadScribeError } from "@radscribe/sdk";
try {
await client.workflows.create();
} catch (err) {
if (isRadScribeError(err)) {
console.error(err.status, err.code, err.message, err.details);
}
}API surface (rk_* → /v1)
Full method explanations: docs/SDK_COMPLETE_API_GUIDE.md.
| Resource | Methods |
|----------|---------|
| auth | login |
| organization | get, listMembers, inviteMember, updateMember, removeMember, listInvites, getUsage |
| workflows | create, get, setPatient, transcribeAndCorrect, finalize, cancel |
| patients | create, get, list, listPage, update, parseVoice, listReports |
| pipeline | correct, detectModality, generateReport, transcribeAndCorrect |
| transcriptions | create (requires workflowId at awaiting_transcript) |
| templates | list, get, create, modalities, detectModality |
| reports | create, createDraft, get, list, update, generate, share, getShared, revokeShare, listEvents, addAttachments, listAttachments |
| vocab | get, addCustom |
| calibration | departments, getProfile, addVocabularyWord, setDepartment |
| studies | create, list, transition |
| jobs | get, wait |
| usage | get (metered metrics — not credit balances) |
| webhooks | create, list |
| dictation | connect → sendAudio / close |
Environment variables
| Variable | Description |
|----------|-------------|
| RADSCRIBE_API_KEY | Partner API key (rk_test_… / rk_live_…) |
| RADSCRIBE_BASE_URL | Required API origin (e.g. https://radscribe-api.mightium.ai) |
| RADSCRIBE_HOST_ENV | Optional override: demo / live / local for key×host checks |
License
Proprietary — not open source. Full agreement:
https://unpkg.com/@radscribe/sdk/LICENSE.md
Commercial licensing: [email protected]
