ionworks-api Python package lets you run simulations and submit parameterization pipelines programmatically. For installation and authentication, see the Python API client page.
Running simulations
Useclient.simulation to run simulations. A simulation requires a parameterized model and a protocol in UCP format.
Single simulation
design_parameters is a single-simulation convenience field on protocol(). Pass a flat
dict[str, float] of parameter overrides — the client translates them internally to a
one-row discrete DOE before submission. Use it when you want to vary one or more design
parameters for a single run without writing out the full DOE schema.
In
protocol(), design_parameters and design_parameters_doe are mutually exclusive,
and any DOE you supply must resolve to exactly one simulation. Passing both, or a DOE
that would expand to multiple simulations, raises ValueError — use
protocol_batch for multi-simulation
sweeps instead.Waiting for results
Usewait_for_completion to poll until the simulation finishes. The method detects failed and canceled jobs immediately rather than waiting for the timeout.
raise_on_failure=False to get the result dict instead of raising an exception when a simulation fails:
Batch simulations with design of experiments
Run multiple simulations across a parameter sweep usingprotocol_batch:
| Type | Fields | Description |
|---|---|---|
discrete | values | Specific values to test |
range | min, max, count | Evenly spaced values between min and max |
normal | mean, std, count | Values sampled around the mean |
grid (all combinations), random, latin_hypercube.
Retrieving simulation data
get_result returns a typed SimulationResult dataclass with three fields:
| Field | Type | Description |
|---|---|---|
result.time_series | DataFrame | One row per time point; columns are signal names (e.g. "Time [s]", "Voltage [V]", "Current [A]"). |
result.steps | DataFrame | One row per protocol step (e.g. "Step count", "Step type", "Duration [s]"). |
result.metrics | dict[str, Any] | Scalar metrics computed over the run (e.g. cycle-level summaries). |
time_series and steps are returned as polars DataFrames by default. Call set_dataframe_backend("pandas") once at session start to receive pandas DataFrames instead.
Discharge capacity [A.h] and Charge capacity [A.h] in time_series
reset to 0 at each step boundary. Use "Step count" to join time_series
to steps, or accumulate per-step end values if you need a continuous
cumulative capacity trace.Running pipelines
Pipelines combine data fitting, calculations, and validation steps for battery model parameterization. Useclient.pipeline to submit and manage pipelines.
Pipelines require a
project_id. Set the IONWORKS_PROJECT_ID
environment variable (or pass project_id= to Ionworks(...)) to
configure a default project, or include
project_id in the pipeline config explicitly. The deprecated
PROJECT_ID env var is still accepted as a fallback.Submitting a pipeline
Waiting for pipeline completion
Getting pipeline results
Data references in pipelines
Use these prefixes to reference data sources in pipeline configs:| Prefix | Example | Description |
|---|---|---|
db: | "db:measurement-id" | Reference an uploaded measurement by ID |
file: | "file:data.csv" | Load a local CSV file |
folder: | "folder:data_dir/" | Load from a local directory |
The
folder: scheme expects a directory containing time_series and
steps files. Both .parquet and .csv are supported, and parquet is
preferred when both are present. For example, a folder with
time_series.parquet and steps.parquet (or .csv) loads correctly.PyBaMM model support
Pipeline configs accept PyBaMM model objects directly. The client auto-serializes them before sending:Running simple pipelines
For pipelines that contain a single data fit or a single validation step, useclient.simple_pipeline instead of client.pipeline. A simple pipeline
is a lightweight, fire-and-forget alternative: you submit one config and the
server runs it end-to-end as a single job, returning a flat
parameter_values result.
When to use simple pipelines
Use client.simple_pipeline when | Use client.pipeline when |
|---|---|
Your config has at most one data_fit or validation element | Your config chains multiple data fits, calculations, or validations |
| You want fire-and-forget execution with a single result payload | You need per-element status tracking and intermediate results |
You want a flat parameter_values dict back | You need cumulative parameter threading across elements |
Simple pipelines require a
project_id. Set the IONWORKS_PROJECT_ID
environment variable (or pass project_id= to Ionworks(...)) to
configure a default project, or pass
project_id= explicitly on each call.Submitting a simple pipeline
elements dict may contain at most one data_fit or validation
element. Helper entries such as entry elements are allowed and are
evaluated before the fit.
Accepted element_type values
Each element’s element_type accepts the canonical wire values below.
For backwards compatibility, configs authored against earlier versions of
the app may also use the legacy display labels in parentheses — the
server normalizes them to the canonical value before running the job.
| Canonical value | Legacy alias | Use for |
|---|---|---|
entry | "Direct Entry" | Seeding parameter values or model selection before the fit |
data_fit | "Data Fit", "datafit" | The single fitting step |
calculation | "Calculation" | Derived parameter calculations |
validation | "Validation" | A single validation step (in place of a data_fit) |
element_type causes the job to fail with a ValueError listing the
accepted values.
data_fit elements in simple pipelines are evaluated in parallel using
the same distributed worker pool as regular pipelines. No extra
configuration is required — set optimizer.population_size as usual
and the server fans the population evaluations out across workers.Execution options
Pass anoptions dict to create to control runtime execution behavior
for the submitted pipeline. Options are submission metadata — they affect
how the server runs the job but are not stored as part of the pipeline
config.
| Option | Type | Default | Effect |
|---|---|---|---|
live_progress_updates | bool | None | None (worker picks a sensible default for the job type) | When True, the worker writes checkpoint progress to the database during execution so you can poll intermediate progress. When False, checkpoints are skipped for better performance. |
options (along with project_id, name, or
description) directly in the config dict — create lifts them out of
the config before submission. Arguments passed explicitly to create
take precedence over values found in the config.
Waiting for completion
wait_for_completion polls until the pipeline reaches a terminal status
(completed, failed, or canceled) and returns the final record.
summary_stats block
alongside parameter_values.
If the pipeline does not finish within timeout, a TimeoutError is
raised. If it ends in failed and raise_on_failure=True (the default),
an IonworksError is raised with the server-side error message.
Listing, filtering, and sorting
list returns a paginated response with items, count, and total.
String filters accept either an exact value or
Supabase operator syntax
such as ilike.%foo% or in.(completed,failed).
Updating, cancelling, and deleting
Handling errors
Managing studies
Useclient.study to create, list, update, and delete studies. Studies are scoped to a project.
All client.study.* methods accept project_id as an optional keyword
argument. When omitted, they use the default project
configured on the client (or resolved from IONWORKS_PROJECT_ID). Pass
project_id= explicitly to override on a per-call basis.
Listing studies
name, name_exact, order_by, order.
Getting a study
Creating a study
Updating a study
Assigning simulations and measurements
Deleting a study
Managing protocols
Useclient.protocol to validate UCP protocols.
Validating a protocol
Finding input references
Findinput[...] placeholders in a protocol string, useful for building experiment parameter forms.
Converting UCP to a vendor protocol file
Useclient.protocol.convert to translate a UCP YAML protocol into the native file format used by a commercial cycler. This is the reverse of the commercial protocol upload flow — start from a protocol designed in Ionworks and produce a file you can run on hardware.
Supported target formats: maccor, neware, arbin, biologic, novonix.
Some UCP features map cleanly across all formats, but each vendor has its own
syntax and limitations (see Differences between commercial
protocols).
If a UCP construct can’t be expressed in the target format, the conversion
returns an error naming the unsupported step (see Export-time
validation
for the specific features each target format rejects). Validate the output
by reuploading it through the commercial protocol
flow before running it on a real
cycler.
Next steps
Simulations
Learn about running simulations in Ionworks Studio.
Protocol reference
Full reference for the Universal Cycler Protocol format.
Uploading data
Upload and manage cell data via the Python API.
Build API
List and retrieve models and parameterized models.