Skip to main content

Schemas

Complete Pydantic schema reference for the TransPlan API. Source: backend/models/schemas.py.

PatientProfile

Input schema for simulation requests.

class PatientProfile(BaseModel):
organ: Literal["kidney", "liver", "heart", "lung", "pancreas", "intestine"]
blood_type: str # pattern: ^(A|B|AB|O)[+-]$
age: int # 1–99
sex: Literal["male", "female"]
urgency: int # 1–4
insurance: Optional[Literal["medicare", "medicaid", "private", "uninsured"]]
weight_lbs: Optional[float] # > 0, < 1000
height_inches: Optional[float] # > 0, < 120
cpra: Optional[int] # 0–100 (kidney only)
meld: Optional[int] # 6–40 (liver only)
las: Optional[float] # 0–100 (lung only)
home_center: Optional[str] # Patient's current listing center (city or center code)
adjust_for_cause_of_death: bool # default False; apply COD donor multiplier
use_copula: bool # default False; Clayton copula for correlated competing risks
custom_weights: Optional[dict] # Custom scoring weights { category: decimal_fraction }

Field Details

organ

One of six transplantable solid organs. This field determines which wait time distribution, competing risks model, and clinical score multiplier are used.

blood_type

ABO type with Rh factor. Must match the regex ^(A|B|AB|O)[+-]$. Valid values: A+, A-, B+, B-, AB+, AB-, O+, O-

urgency

Urgency level on a 1-4 scale.

ValueMeaning
1Elective / stable
2Moderate urgency
3High urgency
4Emergency (Status 1A/1B equivalent)

cpra

Calculated Panel Reactive Antibody percentage (kidney only), ranging from 0 to 100. At 0%, the patient has no sensitization and will accept most donors. At 80% or above, the patient is highly sensitized and needs a rare compatible donor, which significantly extends wait time. At 99% or above, only extremely rare matches exist.

meld

Model for End-Stage Liver Disease score (liver only), ranging from 6 to 40. Scores of 6-14 indicate low urgency. Scores of 15-24 indicate moderate urgency with expedited allocation. Scores of 25-35 carry high urgency with significant mortality risk. Scores above 35 trigger emergency allocation with the shortest expected wait.

las

Lung Allocation Score (lung only), ranging from 0 to 100. Higher scores indicate greater urgency and receive allocation priority.


CityProbability

Per-center simulation output.

class CityProbability(BaseModel):
city: str # Center or city name (display label)
state: str # Full state name
center_code: str = "" # SRTR center code (e.g. "PAPT")
center_name: str = "" # Full center name
lat: Optional[float] # Center latitude
lon: Optional[float] # Center longitude
p_transplant_6mo: float # [0, 1]
p_transplant_12mo: float # [0, 1]
p_transplant_24mo: float # [0, 1]
p_transplant_36mo: float # [0, 1]
confidence_interval_95: tuple[float, float] # for 24-month probability
median_wait_months: float # > 0
competing_risks: Optional[dict]
outcomes: Optional[dict] # Post-transplant graft/patient survival
trends: Optional[dict] # Historical wait-time trends

SimulationResult

Top-level response schema.

class SimulationResult(BaseModel):
patient: PatientProfile
cities: list[CityProbability] # ranked by p_transplant_24mo descending
iterations: int
elapsed_seconds: float
inference_mode: str # "monte_carlo", "bayesian", or "mcmc"

HealthResponse

GET /health response.

class HealthResponse(BaseModel):
status: Literal["ok", "degraded"]
version: str
data_freshness: dict # { filename: iso_timestamp_string }
data_files_loaded: int

ParameterImpact

Per-parameter sensitivity data (part of SensitivityResult).

class ParameterImpact(BaseModel):
parameter: str # e.g., 'cpra', 'meld', 'las', 'urgency'
label: str # Human-readable name
baseline_value: float # Patient's current value
low_value: float # Most favorable extreme tested
high_value: float # Least favorable extreme tested
p24_baseline: float # p_transplant_24mo at patient's actual value
p24_at_low: float # p_transplant_24mo at low_value
p24_at_high: float # p_transplant_24mo at high_value

SensitivityResult

POST /sensitivity response.

class SensitivityResult(BaseModel):
patient: PatientProfile
city: str # City or center used for analysis
center_code: str = "" # SRTR center code (if center-level)
impacts: list[ParameterImpact] # Sorted by magnitude (largest first)
iterations: int
elapsed_seconds: float

CityEquity

Per-city equity metrics (part of EquityAnalysisResult).

class CityEquity(BaseModel):
city: str
state: str
center_code: str = "" # SRTR center code
center_name: str = "" # Full center name
gini_coefficient: float # 0 = equality, 1 = total inequality
p24_range: tuple[float, float] # (min, max) p_transplant_24mo across profiles
median_wait_range: tuple[float, float] # (min, max) median wait across profiles
dimension_disparities: dict[str, list[dict]]
# e.g., { 'blood_type': [{value, p24, median_wait}, ...], ... }

EquityAnalysisResult

POST /equity-analysis response.

class EquityAnalysisResult(BaseModel):
organ: str
cities: list[CityEquity] # Sorted by gini ascending (most equitable first)
overall_gini: float # Gini across all profiles x all centers
profiles_simulated: int # Total demographic profiles (48)
iterations_per_profile: int
elapsed_seconds: float
disclaimers: list[str] # Mandatory limitation disclaimers

Frontend Field Mapping

The frontend form uses camelCase, and api-client.js normalizes these to snake_case before sending to the API.

Form fieldAPI field
bloodTypeblood_type
weightLbsweight_lbs
heightInchesheight_inches
cpracpra
meldmeld
laslas
urgencyurgency
organorgan
ageage
sexsex
homeCenterhome_center
adjustForCauseOfDeathadjust_for_cause_of_death