Skip to content

Developers

SDK documentation

The Python SDK wraps every public capability behind typed resources with exactly-once helpers. Requires Python ≥ 3.12. TypeScript integrates through the same REST contract shown below.

Installation

pip install biomedora-client     # branded distributionpip install biomedora-sdk        # identical API, neutral name

Quickstart

from biomedora_sdk import Client

client = Client(api_key="YOUR_API_KEY",
                base_url="https://api.biomedora.com")

caps = client.capabilities.get()
print(caps.abstraction)

doc = client.documents.create(
    content=open("discharge_summary.txt").read(),
    patient_id="patient_123",
    idempotency_key="seed-load-0001",
)

job = client.jobs.wait(doc["job_id"])          # polls until terminal
entities = client.documents.entities(doc["document_id"])

Resource map

ResourceMethods
patientscreate · get · summary · documents · events · timeline · graph · graph_query
documentscreate (Idempotency-Key) · presign · process · entities · coreference · temporal_events
deidentifytext · validate
nlpanalyze · assertions · temporal · link
searchquery
reasoningquery (validated claims with attribute access)
chatsessions · messages
jobsget · list · cancel · wait (polling helper)
billingaccount · subscription · invoices · credits · usage · quota
pricingestimate · estimate_reasoning
llmmodels · preferences · set_default
storagesummary · timeseries · by_type · forecast

Error handling

Platform errors parse into a typed ApiError carrying the stable code, category, request ID, and retryability from the standard envelope.

from biomedora_sdk import ApiError

try:
    client.patients.timeline(patient_id="patient_123")
except ApiError as e:
    print(e.code)        # e.g. MODEL_NOT_ENTITLED
    print(e.category)    # entitlement | validation | privacy | ...
    print(e.retryable)
    if e.status == 429:
        time.sleep(retry_after)

Pagination

page = client.patients.documents(patient_id, limit=50)
while page:
    for doc in page["items"]:
        handle(doc)
    cursor = page.get("next_cursor")
    if not cursor:
        break
    page = client.patients.documents(patient_id, limit=50, cursor=cursor)

Streaming chat

# Server-sent events — validated answer arrives only in answer.completed
POST /v1/chat/sessions/{session_id}/messages/stream
Accept: text/event-stream

event: retrieval.completed
event: claim_validation.completed
event: answer.completed        <- final, evidence-validated payload

Preliminary text is never presented as final — the validated answer ships exclusively in answer.completed, after claim validation.

TypeScript (typed REST)

A first-party TypeScript SDK is on the roadmap. Today, integrate over REST with generated OpenAPI types:

// TypeScript integration via typed REST
type ReasoningAnswer = {
  answer: string;
  claims: { status: string; confidence: number; text: string; citations: number[] }[];
  citations: { id: number; document_id: string; page: number; section: string; sentence: string }[];
  uncertainty?: string;
  metadata: { reasoning_mode: "deterministic" | "model_reasoning"; model: string };
};

async function ask(question: string, patientId: string): Promise<ReasoningAnswer> {
  const res = await fetch(`${process.env.BIOMEDORA_BASE_URL}/v1/reasoning/query`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.BIOMEDORA_TOKEN}`,
      "Content-Type": "application/json",
      "Idempotency-Key": crypto.randomUUID(),
    },
    body: JSON.stringify({ question, patient_id: patientId }),
  });
  if (!res.ok) throw new Error(`BioMedora ${res.status}: ${await res.text()}`);
  return res.json();
}

Full endpoint-level reference lives in the API reference — or try everything in the playground.