Skip to main content
Once data is uploaded, you can read it back using the ionworks-api Python client. This page covers listing and filtering resources, retrieving full measurement detail, local caching, in-Python plotting, and error handling. For installation and authentication, see the Python API client page. For uploading, see uploading data.
You can find the ID for any cell specification, instance, or measurement from the data visualization pages in Ionworks Studio. The ID is displayed in the URL and in the detail panels.

Listing resources

Filtering and ordering

All list() methods accept keyword-only filter parameters so you can narrow results server-side instead of fetching everything and filtering in Python.
Filters work the same way across all three resource types and can be combined with pagination and ordering in a single call:
Cell measurements support additional date filters for the measurement start time:

Filter parameters

Filter parameters can be combined freely with each other and with the limit/offset pagination parameters. The .total property on the returned PaginatedList reflects the total count after filters are applied.

Pagination

All list() calls return a PaginatedList. The limit and offset parameters control which page is fetched.
The returned PaginatedList behaves like a regular Python list (iterate, index, check length) and also exposes: To iterate through all results:

Resolving a measurement by name

When you know the human-readable names of a measurement and its parents but not their ids, use client.resolve_measurement() instead of hand-walking the spec → instance → measurement hierarchy:
The method filters each level server-side by exact name and returns the matching CellMeasurement. It raises IonworksError with:
  • status_code=404 if any level has no match.
  • status_code=409 if a name is ambiguous within its parent — in that case, resolve by id instead (for example, via the data visualization pages in Ionworks Studio).

Measurement detail

client.cell_measurement.detail() retrieves the full measurement and adapts its response based on the measurement type.
Returns time series data, step statistics, and cycle metrics:

Linking to the web app

Use client.urls.measurement() to build a link to a measurement’s detail page in the Ionworks web app. This is useful when you want to surface a clickable link from a notebook, script, or report so collaborators can jump straight to the measurement in Ionworks Studio.
A common pattern is to render a link next to each result while iterating through measurements:
client.urls exposes the same helper for every routed resource — studies, simulations, parameterized models, pipelines, optimizations, protocols, materials, cell specs, and cell instances. See Web app URL helpers for the full reference. Navigator is an opt-in helper that walks the spec → instance → measurement hierarchy and memoises every list and fetch call in memory. Use it when you want to iterate over many specs, instances, or measurements in a single script or notebook and avoid repeating the same API calls. Reach for Navigator when:
  • You’re writing an analysis script that loops over every measurement on one or more cell specs.
  • You want deterministic iteration order — listings are returned sorted by name.
  • You want pagination handled automatically without managing limit and offset yourself.
The underlying sub-clients (client.cell_spec, client.cell_instance, client.cell_measurement) remain the primary API. Navigator is a thin layer on top — use it when you want a single cached view of the hierarchy, and use the sub-clients directly for one-off reads or writes.
Each entity is fetched at most once per Navigator instance. Calling nav.instances("CellA") twice returns the same list without a second API round-trip; the same applies to measurements, steps, and time_series.

Configuration

Looking up a single spec

Raises KeyError with the list of available spec names if the name doesn’t match — useful for catching typos.

Invalidating the cache

Battery data is immutable once uploaded, so the only staleness mode is “a new sibling appeared on the platform.” For long-running notebooks where new data may have been uploaded mid-session, you can drop part or all of the cache:
Invalidation cascades downward: dropping a spec also drops its instances and their measurements; dropping an instance also drops its measurements.
Navigator caches in memory for the lifetime of the instance. For cross-process or cross-session caching of measurement data on disk, see Local caching below — the two layers compose.

Local caching

The ionworks-api client automatically caches measurement data to disk so repeated reads are fast and avoid unnecessary API calls. Caching is enabled by default and applies to the steps, cycles, steps_and_cycles, and time_series methods on cell_measurement. When you call a method like client.cell_measurement.steps(measurement_id), the client checks a local cache directory before making an API request. If a cached copy exists and hasn’t expired, it’s returned directly. Otherwise, the client fetches from the API, caches the result, and returns it. Cached data is stored as Parquet files in ~/.ionworksdata_cache by default and expires after one hour.

Skipping the cache

Every data-fetching method accepts a use_cache parameter. Set it to False to force a fresh API call without reading from or writing to the local cache:

Configuring the cache

Cache configuration is global. Changes affect all subsequent API calls in the same Python process.

Plotting from Python

DataLoader includes a plot_data() method for quick matplotlib-based visualization of measurement data. The plot displays voltage and current over time, with an additional temperature subplot when temperature data is available.
The method returns a matplotlib (Figure, Axes) tuple so you can customize the plot further. Pass show=True to display the plot immediately:
plot_data() automatically loads time series data from the server if it hasn’t been fetched yet.
For the interactive in-browser viewer (with filters, step overlays, SQL), see visualizing data.

Inline time series size limit

When you pass a pandas or polars DataFrame directly in an API call (for example, as part of a pipeline configuration), the client enforces a maximum of 1,000 rows for inline time series data. The same limit applies to "file:..." and "folder:..." references, since the client reads them from your local machine and inlines their contents. Larger datasets should be uploaded as measurements first, then referenced by ID.
To work with larger datasets, upload first and reference by ID:

Exporting DataLoader configurations

If you have a DataLoader that references a database measurement and you want to export a self-contained configuration (for example, to share with a colleague), use to_local() to embed the data inline:
to_local() fetches all time series and step data from the server immediately. For very large measurements, this may take a moment.

Error handling

The client raises exceptions for common error cases:
  • Missing or invalid API credentials
  • API request errors (raises IonworksError with details)
  • Inline time series exceeding 1,000 rows (raises MeasurementValidationError, a subclass of IonworksError)
See inline time series size limit above for the MeasurementValidationError handling pattern.

API error format

All API errors return a consistent JSON structure:
Common HTTP status codes:

Full API reference

For the complete Python API reference, see the ionworks-api documentation.

Next steps

Visualize data

Explore uploaded data with the interactive in-browser viewer.

Uploading data

End-to-end upload workflow for specs, instances, and measurements.

Measurements

The three measurement types in detail.

Simulation API

Run simulations and pipelines via the Python API.