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 nameQuickstart
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
| Resource | Methods |
|---|---|
| patients | create · get · summary · documents · events · timeline · graph · graph_query |
| documents | create (Idempotency-Key) · presign · process · entities · coreference · temporal_events |
| deidentify | text · validate |
| nlp | analyze · assertions · temporal · link |
| search | query |
| reasoning | query (validated claims with attribute access) |
| chat | sessions · messages |
| jobs | get · list · cancel · wait (polling helper) |
| billing | account · subscription · invoices · credits · usage · quota |
| pricing | estimate · estimate_reasoning |
| llm | models · preferences · set_default |
| storage | summary · 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 payloadPreliminary 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.