API Documentation

Battery degradation prediction API. Physics-based, 30ms per simulation.

Base URL: https://cozy-hope-production-cb41.up.railway.app

Quick Start

Get a prediction in 60 seconds. No credit card required.

1. Get your API key

curl -X POST https://cozy-hope-production-cb41.up.railway.app/api/trial \
  -H "Content-Type: application/json" \
  -d '{"email": "you@company.com"}'

2. Run your first prediction

curl -X POST https://cozy-hope-production-cb41.up.railway.app/api/predict \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "silicon_fraction": 0.20,
    "cycles": 1000,
    "c_rate": 1.0,
    "temperature_c": 25.0,
    "include_modes": true
  }'

Python (copy and run)

import requests

API_KEY = "your_api_key_here"  # from step 1
BASE = "https://cozy-hope-production-cb41.up.railway.app"

# Run a degradation prediction
resp = requests.post(f"{BASE}/api/predict",
    headers={"x-api-key": API_KEY},
    json={
        "silicon_fraction": 0.20,   # 20% silicon content
        "cycles": 1000,             # simulate 1,000 charge cycles
        "c_rate": 1.0,              # 1C charge rate
        "temperature_c": 25.0,      # 25°C operating temperature
        "soc_low": 0.1,             # lower SOC limit (0.1 = discharge to 10% SOC)
        "include_modes": True,      # include degradation breakdown
    }
)
data = resp.json()

print(f"Final retention: {data['final_retention_pct']:.1f}%")
print(f"Simulation time: {data['audit']['wall_time_ms']:.0f}ms")

# What's killing the cell?
modes = data["modes"]
print(f"LLI (SEI growth): {modes['lli_pct'][-1]:.1f}%")
print(f"LAM-Si (cracking): {modes['lam_si_pct'][-1]:.1f}%")
print(f"Transport: {modes['transport_pct'][-1]:.1f}%")

Python SDK (coming soon)

A typed Python SDK is in development. For now, the requests library above is the recommended integration path. Contact us if you need early SDK access.

Authentication

All prediction endpoints require an API key passed in the x-api-key header.

x-api-key: sp_free_abc123...

Free trial keys (sp_free_ prefix) include 50 simulations/month. Paid keys (sp_ prefix) include 2,500-10,000 simulations/month depending on tier.

Predict

POST/api/predictrequires API key

Run a single degradation simulation. Returns capacity retention curve, degradation mode decomposition, knee point detection, and safety metrics.

Parameters

silicon_fractionfloatdefault: 0.2
Silicon content by weight (0.0-0.50)
cyclesintdefault: 1000
Number of charge-discharge cycles (1-50,000). 25-yr marine ferry duty ≈ 36,500; larger fleets use /api/batch_predict.
c_ratefloatdefault: 1
Charge/discharge rate in C (0.05-10.0)
temperature_cfloatdefault: 25
Operating temperature in Celsius (-40 to 80). Also routes to ambient thermal node; T < 0°C activates cold-T plating mechanism (Yang-Leng-Ge style, calibrated by anchor pending real cold-cycle data — see /methodology).
include_modesbooldefault: true
Include degradation mode decomposition (LLI, LAM-Si, LAM-Gr, transport)
include_safetybooldefault: false
Include thermal runaway risk and safety metrics
sample_everyintdefault: 10
Return every Nth cycle (reduces response size)
seasonal_amplitude_cfloatdefault: 0
Half-amplitude of annual temperature swing in °C
diurnal_amplitude_cfloatdefault: 0
Half-amplitude of daily temperature swing in °C
soc_lowfloatdefault: 0
Lower SOC bound for cycling window (0.0-1.0). Set to 0.2 for 20-100% DOD cycling.
soc_highfloatdefault: 1
Upper SOC bound for cycling window (0.0-1.0). Set to 0.8 for 0-80% DOD cycling.
presetstring
Use a scenario preset (e.g. "ev_standard", "desert_outdoor")
calibrated_presetstring
Use a calibrated preset (e.g. "NatComms_20Si_LPD")

V18.4 fields (added 2026-05-10)

initial_sohfloatdefault: 1
Aged-cell starting state of health (0.5-1.0). 1.0 = fresh; 0.78 = second-life NMC pack at 78% SOH. Loss is empirically apportioned across LLI / LAM-Si / SEI / electrolyte / porosity consistent with v18.3 mode decomposition. Unlocks second-life modeling, mid-fleet recalibration, year-3 EDV pack projections.
nano_Si_fractionfloatdefault: 0
Fraction of Si present as engineered nanoparticles (0.0-1.0). Affects mechanical resilience and volume-expansion physics. Bulk-Si default = 0.0; Sila/Group14 SCC55-style ≈ 0.3-0.6; pure-nano Nexeon-style ≈ 1.0.
bet_area_multiplierfloatdefault: 1
BET-area scaling factor for SEI growth on Si surfaces (0.5-10.0). Nano-Si has BET surface area ~3-10× higher than bulk Si per unit mass; SEI consumes Li faster on high-BET materials. Baseline Si-Gr = 1.0; Sila/G14-style = 1.5-2.0; pure-nano = 3.0-5.0. Effect scales with f_Si.
cathode_chemistrystringdefault: "NMC"
Cathode chemistry. Supported: NMC, NMC_532, NMC_622, NMC_811. Roadmap (will 422-reject): LFP, LFP_GRAPHITE, NCA, LMO, LMFP, LCO. The engine models silicon-graphite with NMC-family cathodes; sending silicon_fraction=0 does NOT switch to LFP physics.
predict_threshold_pctfloat
If provided (e.g. 80, 70), response includes cycle_to_threshold with the interpolated cycle at which retention crosses the threshold. Avoids the chained calibrate→predict→interpolate pattern.

Response

{
  "version": "18.3",
  "output_schema_version": "2026-05-10",
  "cycles": [1, 11, 21, ...],
  "retention_pct": [100.0, 99.76, 99.51, ...],
  "final_retention_pct": 77.887,
  "total_cycles": 1000,
  "knee_point_cycle": {
    "detected": false,
    "cycle": null,
    "retention_pct": null,
    "rate_acceleration": null,
    "description": "No knee point detected (linear degradation)"
  },
  "invariants_passed": true,
  "modes": {
    "lli_pct":        [0.0, 0.04, ...],
    "lam_si_pct":     [0.0, 0.01, ...],
    "lam_gr_pct":     [0.0, 0.00, ...],
    "transport_pct":  [0.0, 0.00, ...],
    "dominant_mode":  ["LLI", "LLI", ..., "LAM_Si"],
    "lli_attribution": {
      "sei_fraction":     [0.95, 0.96, ...],
      "plating_fraction": [0.00, 0.00, ...],
      "crack_fraction":   [0.05, 0.04, ...],
      "cei_fraction":     [0.00, 0.00, ...]
    }
  },
  "audit": {
    "run_id": "abc123",
    "model_version": "18.3",
    "output_schema_version": "2026-05-10",
    "config_hash": "9c1f...",
    "request_hash": "f2d8...",
    "timestamp": "2026-05-12T13:30:00Z",
    "platform_info": {"python": "3.11", "numpy": "..."},
    "status": "ok"
  },
  "compute_time_s": 0.039
}

knee_point_cycle is always an object; check .detected before reading.cycle.

Dual Predict (Uncertainty)

POST/api/dual_predictrequires API key

Run a dual-model simulation with automatic uncertainty quantification. Returns central prediction plus pessimistic/optimistic bounds using opposing-bias averaging (Richardson extrapolation).

Additional Parameters

bias_fractionfloatdefault: 0.15
Perturbation magnitude for opposing-bias models (0.05-0.50). Default 0.15 = ±15% rate perturbation.

All other parameters are the same as /api/predict.

Response

{
  "version": "18.1",
  "method": "dual_model_averaging",
  "bias_fraction": 0.15,
  "cycles": [0, 10, 20, ...],
  "central_retention_pct": [100.0, 99.2, ...],
  "pessimistic_retention_pct": [100.0, 99.0, ...],
  "optimistic_retention_pct": [100.0, 99.4, ...],
  "final_retention_pct": 77.94,
  "envelope_width_final": 5.81,
  "bias_cancellation_pct": 98.3,
  "dma_invariants_passed": true,
  "compute_time_s": 0.062
}

Batch Predict (fleet-scale)

POST/api/batch_predictrequires API key

Run up to 200 predictions in a single request. Designed for fleet ops (5k-50k device pipelines that would otherwise hit the API one-config-at-a-time). Synchronous: returns when all sims complete. For larger fleets, pipeline multiple batches in parallel. True async-queue with webhook callback is Enterprise roadmap.

Request body is a JSON array of prediction configs. Each element follows the /api/predict schema. Maximum 200 configs per request.

Example request

curl -X POST https://cozy-hope-production-cb41.up.railway.app/api/batch_predict \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_KEY" \
  -d '[
    {"silicon_fraction": 0.20, "cycles": 1000, "sample_every": 100},
    {"silicon_fraction": 0.10, "cycles": 1000, "initial_soh": 0.80, "sample_every": 100},
    {"silicon_fraction": 0.05, "cycles": 1000, "c_rate": 2.0, "sample_every": 100}
  ]'

Response

{
  "version": "18.3",
  "output_schema_version": "2026-05-10",
  "batch_size": 3,
  "n_successful": 3,
  "n_failed": 0,
  "compute_time_s": 0.137,
  "results": [
    {"index": 0, "cycles": [...], "retention_pct": [...], "final_retention_pct": 87.696, "run_id": "abc..."},
    {"index": 1, "cycles": [...], "retention_pct": [...], "final_retention_pct": 76.609, "run_id": "def..."},
    {"index": 2, "cycles": [...], "retention_pct": [...], "final_retention_pct": 86.676, "run_id": "ghi..."}
  ]
}

Per-element errors do not abort the batch — failed configs return {"index": i, "error": "..."} at their index. Counts billing as N simulations (one per successful element).

Calibrate (Auto-Fit)

POST/api/calibraterequires API key

Fit the model to your experimental data. Provide cycle-retention pairs and the model automatically optimizes its degradation parameters to match your cell's behavior. Returns the fitted prediction and accuracy metrics.

Parameters

target_dataobjectrequired
Your experimental data. Must contain cycle and retention_pct arrays with at least 3 data points.
silicon_fractionfloatdefault: 0.2
Silicon content of the cell being fitted
c_ratefloatdefault: 1
C-rate used in the experiment
temperature_cfloatdefault: 25
Temperature during the experiment
max_iterationsintdefault: 300
Maximum optimizer iterations (capped at 500)

Example

import requests

resp = requests.post(f"{BASE}/api/calibrate",
    headers={"x-api-key": API_KEY},
    json={
        "target_data": {
            "cycle": [0, 100, 200, 300, 400, 500],
            "retention_pct": [100.0, 97.5, 95.0, 92.0, 88.5, 84.0]
        },
        "silicon_fraction": 0.15,
        "c_rate": 1.0,
        "temperature_c": 25.0
    }
)
cal = resp.json()
print(f"RMSE: {cal['calibration']['rmse']:.2f}%")
print(f"Grade: {cal['calibration']['grade']}")
print(f"R²: {cal['calibration']['r_squared']:.4f}")

Response

{
  "version": "18.1",
  "calibration": {
    "rmse": 0.23,
    "mae": 0.18,
    "grade": "A+",
    "r_squared": 0.9994,
    "converged": true,
    "n_iterations": 47,
    "fitted_params": {
      "degradation.SEI_rate_cycling": 5.24e-04,
      "degradation.gamma_Si": 2.09e-05,
      "degradation.crack_SEI_coupling": 4.66e-04,
      "degradation.cracking_rate": 5.57e-07
    }
  },
  "prediction": {
    "cycles": [0, 10, 20, ...],
    "retention_pct": [100.0, 99.7, ...]
  },
  "final_retention_pct": 83.5,
  "compute_time_s": 4.2
}

Free Trial

POST/api/trial

Create a free trial API key. No credit card required. 50 simulations per month.

emailstringrequired
Your email address

Response

{
  "api_key": "sp_free_abc123...",
  "email": "you@company.com",
  "monthly_limit": 50
}

Health Check

GET/api/health

Check API status, model version, and available presets. No authentication required.

Response

{
  "status": "ok",
  "service": "Scale Prognostics Battery Degradation API",
  "model_version": "18.1",
  "latency_ms": 31.2,
  "endpoints": [
    "POST /api/predict",
    "POST /api/dual_predict",
    "POST /api/calibrate",
    "GET /api/health"
  ],
  "scenario_presets": [
    "ev_standard", "premium", "long_life",
    "fast_charge", "temperate_outdoor", ...
  ],
  "calibrated_presets": [
    "NatComms_20Si_LPD", "Kirk_2024_FastCharge", ...
  ]
}

Error Handling

All errors return JSON with an error field.

401Invalid or missing API key
422Parameter out of valid range
429Monthly simulation limit reached
500Simulation failed (server error)
{
  "error": "silicon_fraction must be 0.0-0.50"
}

Usage Notes

Mid-life predictions (starting from degraded state)

Pass initial_soh (0.5–1.0) to simulate a battery already at a known state of health. The starting capacity loss is empirically apportioned across LLI, LAM-Si, SEI, electrolyte, and porosity consistent with the v18.3 mode decomposition; retention_pct is rebased to nameplate fresh capacity in the response. For higher-fidelity fits to an observed degradation history, run/api/calibrate first; the returned rate constants can then be passed into /api/predict via the degradation field.

Charging protocol

The c_rate parameter applies to both charge and discharge. Separate charge/discharge rates and CC-CV protocol support are on the roadmap. For asymmetric protocols, use the dominant (higher-stress) rate as the input.

Rate Limits & Performance

Prediction latency30-50ms (single), 60ms (dual)
Calibration latency2-10 seconds
Monthly quotasFree: 50 | Starter: 2,500 | Professional: 10,000
Burst rateNo per-second throttling. Concurrent requests supported.
Uptime target99.9% availability. Monitor via GET /api/health

One simulation = one API call to /predict, /dual_predict, or /calibrate, regardless of cycle count. Quotas reset monthly (UTC). Overage returns HTTP 429 with upgrade link.

Enterprise

For teams that need more than the self-serve tiers:

Unlimited simulations
On-premise deployment option
Custom SLA with defined uptime and response commitments
Dedicated engineering support with named contact
Scoped API keys (per-user, per-application)
Async batch endpoint with webhook callbacks
Python SDK (pip install scale-prognostics)

Our standard Data Processing Agreement (DPA) is published online and applies to any paid tier. For custom terms or enterprise pricing, contact jason@scaleprognostics.com.