Quickstart
Five minutes from cold visit to your first calibrated prediction. No credit card.
Don’t want to use code? Skip to Step 6 (chat assistant).
Get a free trial key
~60 secFree tier is 50 simulations per month. No credit card. Sign up below or via curl:
Or via curl:
curl -X POST https://cozy-hope-production-cb41.up.railway.app/api/trial \
-H "Content-Type: application/json" \
-d '{"email": "you@yourcompany.com"}'Real email addresses only — placeholder domains (`*.example`, `test*@`) are blocked. Rate-limited to 5 signups per IP per day.
Run your first prediction
~60 secPredict 1,000 cycles of a 20% silicon cell at 1C, 25°C:
import requests
API_BASE = "https://cozy-hope-production-cb41.up.railway.app"
API_KEY = "your-trial-key-from-step-1"
resp = requests.post(
f"{API_BASE}/api/predict",
headers={"x-api-key": API_KEY},
json={
"silicon_fraction": 0.20,
"cycles": 1000,
"c_rate": 1.0,
"temperature_c": 25.0,
"include_modes": True,
},
)
data = resp.json()
print(f"Final retention: {data['final_retention_pct']}%")
print(f"Dominant mode at end: {data['modes']['dominant_mode'][-1]}")
# V0.2.0 — always check the envelope guard
if data.get("validation_warnings"):
for w in data["validation_warnings"]:
print(f" ⚠ [{w['severity']}] {w['message']}")Or use the Python SDK (`pip install scale-prognostics`):
from scale_prognostics import ScalePrognostics
client = ScalePrognostics(api_key="your-trial-key")
result = client.predict(silicon_fraction=0.20, cycles=1000, c_rate=1.0, temperature_c=25.0)
print(f"Final retention: {result.final_retention_pct}%")
if result.has_warnings:
print("Out-of-envelope:", result.out_of_validated_range)Calibrate to your own cell
~90 secThree retention measurements is the minimum. More is better. The engine fits its rate constants to your specific chemistry:
# Replace with your own cycle/retention data
my_data = {
"cycle": [0, 100, 300, 600, 1000],
"retention_pct": [100, 98.0, 95.5, 91.2, 86.5],
}
resp = requests.post(
f"{API_BASE}/api/calibrate",
headers={"x-api-key": API_KEY},
json={
"target_data": my_data,
"silicon_fraction": 0.10,
"c_rate": 1.0,
"temperature_c": 25.0,
# V0.2.0 — recommended for knee-prone cells:
"weight_mode": "by_decade",
"expanded_fit": True, # engages cathode + plating params
"routing": True, # multi-seed consistency check
},
)
data = resp.json()
print(f"Calibration RMSE: {data['calibration']['rmse']}% Grade: {data['calibration']['grade']}")
print(f"Fitted params: {data['calibration']['fitted_params']}")
if data.get("routing"):
print(f"Routing: {data['routing']['dispatch_to']} — {data['routing']['interpretation']}")What you get back: calibration RMSE + grade (A+/A/B/C/D), the fitted rate constants for your cell, and a forward simulation extrapolating beyond your training cycles.
The `routing` field tells you the calibration’s consistency: healthy (single-seed reliable), identifiability (multiple parameter sets fit equally — wider uncertainty), or coverage (try `expanded_fit` or different chemistry).
Get an uncertainty envelope
~60 secDual-Model Averaging runs the simulation twice with opposing parameter perturbations and reports a central prediction plus high/low bounds — Richardson extrapolation in parameter space. Free uncertainty quantification, no Monte Carlo:
resp = requests.post(
f"{API_BASE}/api/dual_predict",
headers={"x-api-key": API_KEY},
json={
"silicon_fraction": 0.20,
"cycles": 1000,
"c_rate": 1.0,
"temperature_c": 25.0,
},
)
data = resp.json()
print(f"Central: {data['final_retention_pct']}%")
print(f"Envelope: ±{data['envelope_width_final'] / 2:.1f}%")
# V0.2.0 — calibration-sensitive cells fall back to single-run nominal
if data.get("dma_status") == "nonlinear_skipped":
print("Note: this cell is in the calibration-sensitive regime;")
print("envelope is heuristic, not bias-cancelled.")Compute your warranty floor
~60 secThe thermodynamic floor — calendar aging only, zero cycling stress. The minimum capacity loss the cell will experience under ideal storage. Below this floor no warranty claim is physically valid:
resp = requests.post(
f"{API_BASE}/api/warranty_floor",
headers={"x-api-key": API_KEY},
json={
"silicon_fraction": 0.10,
"years": 8.0,
"temperature_c": 25.0,
},
)
data = resp.json()
print(f"After 8 years storage: {data['result']['final_retention_pct']}% retention")
print(f"Floor loss: {data['result']['floor_loss_pct']}%")
# Year-by-year — drop into your actuarial spreadsheet
for m in data["milestones"]:
print(f" Year {m['year']}: {m['retention_pct']}% (floor loss {m['floor_loss_pct']}%)")Useful for warranty reserves, residual value modeling, second-life pricing. The cycling-induced loss adds to this floor; never subtracts from it.
Or skip the code: use the chat assistant
~30 secThe chat widget in the bottom-right of every page runs simulations directly. No installation, no API key. Try asking it:
- “Predict the 1,000-cycle retention of a 15% silicon cell at 1.5C, 30°C”
- “What’s the dominant failure mode for an LG M50T at cycle 600?”
- “Compare 0.5C vs 2C cycling on a 20% Si cell — which lasts longer?”
The assistant uses the same engine as the API. It will tell you when it’s outside validated range, the same way the API surfaces `validation_warnings` in JSON.
Where to go next
Stuck on any step? support@scaleprognostics.com