Uploading data to Ionworks Studio follows a three-step hierarchy: create the cell specification (the cell’s blueprint), create a cell instance (a specific physical cell), then upload measurements against that instance. For installation and authentication, see the Python API client page. For reading data back, see reading data.Documentation Index
Fetch the complete documentation index at: https://docs.ionworks.com/llms.txt
Use this file to discover all available pages before exploring further.
Upload workflow
Create or get a cell specification
The spec defines the cell’s materials, electrical ratings, and components.
Step 1: Create or get a cell specification
Step 2: Create or get a cell instance
| Field | Description |
|---|---|
name | Unique identifier for this cell |
batch | Batch or lot number |
date_manufactured | Manufacturing date (optional) |
measured_properties | Cell-specific measured values that differ from the spec (e.g., actual measured capacity, electrode loadings) |
Step 3: Upload a measurement with time series
Upload validation
Before any data is sent to Ionworks Studio, the Python client validates your time series on your machine. The always-on checks catch the most common processing mistakes:- Positive current corresponds to discharge (voltage decreases); charging uses negative current
- Time starts at 0 and is monotonically non-decreasing
Step countexists, starts at 0, and increments by 1- Cumulative columns (capacity, energy) reset at the start of each step
create and create_or_get raise a
MeasurementValidationError and no upload is initiated. See
Troubleshooting below for how to fix each failure.
Strict validation
We recommend passingvalidate_strict=True on every upload. The strict
checks catch subtle bugs introduced during data processing — for example,
large unrecorded time gaps or a time series whose rows have been reordered by
a faulty groupby or partition_by call — before the data lands in Ionworks
Studio and contaminates downstream simulations and fits.
- Each step contains at least 2 data points
Cycle countis constant within each step- No gap between consecutive time samples exceeds 5 hours
- Voltage is continuous between consecutive rows (requires
voltage_window) - No two consecutive same-direction steps deliver a full charge or discharge
(requires
rated_capacityand astepsdataframe inmeasurement_detail) - No single step exceeds 500 % of the rated capacity — emitted as a
UserWarningrather than raising (requiresrated_capacityandsteps)
Providing cell context for richer checks
The voltage-continuity and step-capacity checks need to know the cell’s rated voltage window and capacity. Pass them as keyword arguments:voltage_window skips only the
voltage-continuity check; omitting rated_capacity skips only the
consecutive-full-step and per-step capacity checks. All other strict-mode
checks still run.
The consecutive-full-step and per-step capacity checks also require a
pre-computed step summary under the
steps key of measurement_detail.
If you do not provide one, Ionworks Studio generates step summaries
server-side after upload, but these two client-side checks are skipped.create_or_get accepts the same rated_capacity and voltage_window
arguments and forwards them to create.
Relaxing a single strict check
If a specific strict check is a known false positive for your dataset — for example, a legitimate multi-day rest period that exceeds the 5-hour time-gap threshold — relax only that check withskip_checks rather than turning
strict mode off entirely. This keeps every other guardrail in place
(least-privilege validation).
ionworks.validators.STRICT_CHECK_NAMES):
minimum_points_per_stepcycle_constant_within_steptime_gapsvoltage_continuityconsecutive_same_direction_full_stepsstep_capacity_within_rated
ValueError. Avoid disabling strict mode wholesale unless
you have a documented reason that applies to multiple checks at once.
Idempotent uploads with create_or_get
All three create methods have create_or_get variants that make upload
scripts safely re-runnable — if a resource with the same name already exists,
the client fetches and returns it instead of raising an error.
Duplicate handling
When you callcreate() (not create_or_get) and a resource with the same
name already exists, the API returns a 409 Conflict with the existing
resource’s ID in the detail field:
existing_id lets you fetch the existing record without a separate lookup
if you want to implement your own create-or-get logic.
Inline time series size limit
Time series passed inline (e.g. inside a pipeline configuration) are capped at 1,000 rows — larger datasets must be uploaded as measurements first. See reading data — inline size limit for the error class, workaround, anddb:<measurement_id> reference form.
Automatic payload compression
The Python client automatically compresses request payloads larger than 512 KB using gzip before sending them to the API. This happens transparently — no configuration is needed. For large serialized models or datasets, this can reduce upload sizes significantly.Troubleshooting
Large time gap between consecutive rows
Problem: When uploading withvalidate_strict=True, you receive an error
like:
Time gap of 6.12 h between rows 4201 and 4202 exceeds the maximum allowed gap of 5.0 h.Solution: A gap longer than 5 hours between two consecutive time samples almost always means rows were dropped during processing — for example, a long rest period was recorded as elapsed time in the file but the intermediate rows were stripped. The capacity integral then counts current across the missing interval and reports inflated values. Re-read the raw cycler file without filtering and confirm the time axis is continuous. If your workflow intentionally decimates the data, downsample uniformly rather than removing whole sections, or split the recording into separate measurements at the gap.
Voltage continuity check failed
Problem: When uploading withvalidate_strict=True and a voltage_window,
you receive an error like:
Voltage continuity check failed: 318/3599 (8.8%) of consecutive row pairs have a voltage jump greater than 80% of the rated voltage window.Solution: Ionworks looks at the absolute voltage change between every pair of consecutive rows. If more than 5 % of pairs exceed 80 % of the rated voltage window (
V_max - V_min), the time series is almost certainly out of
chronological order — typically because of a grouping operation like
partition_by("Cycle_raw") that interleaves pulse and rest rows from
different cycles.
Sort your DataFrame by Time [s] before uploading, and avoid any transform
that breaks the natural row order:
Consecutive full-capacity steps in the same direction
Problem: When uploading withvalidate_strict=True, a steps dataframe,
and a rated_capacity, you receive an error like:
Consecutive full-capacity discharge steps detected: step 12 and step 15 each delivered more than 200% of the rated capacity.Solution: “Consecutive” here means the two nearest same-direction steps in the sequence — so step 12 and step 15 are consecutive discharges even if charge steps sit between them. A single measurement should represent one continuous test on a single cell, so two back-to-back full-capacity discharges (or charges) usually mean the file was assembled by concatenating several independent experiments (for example, multiple CC discharges at different C-rates stitched together). Split the source data back into separate measurements before uploading.
If a legitimately long single experiment contains more than two full
charges or discharges in a row — rare, but possible — drop the pre-computed
steps entry from measurement_detail or omit rated_capacity so this
specific check is skipped, and let Ionworks Studio regenerate step
summaries server-side.Step capacity exceeds rated capacity
Problem: When uploading withvalidate_strict=True, a steps dataframe,
and a rated_capacity, you see a UserWarning like:
3 step(s) exceed 500% of the rated capacity. First: step 47 has ‘Discharge capacity [A.h]’ = 0.031 A.h.Solution: This is a soft warning — the upload still proceeds — but it signals that something is probably wrong with your step boundaries or that the capacity integral was inflated across an unrecorded time gap. Inspect the flagged step, verify it represents a single charge or discharge, and re-check the
Step count column for gaps. Fixing the underlying time-gap or step
boundary issue usually clears the warning.
Next steps
Measurements
The three measurement types — time series, properties, file — in detail.
Reading data
List, filter, paginate, and retrieve measurement data.
Preparing data
Read cycler files into the Ionworks format before uploading.
Data format
Recognized columns, quantity format, and sign conventions.