measurement_type
that determines what data it stores and how you create it.
Measurement types
Common fields
Every measurement — regardless of type — accepts these optional metadata fields:Recording what a measurement ran
Two fields describe the test, and they are not interchangeable:
Prefer
protocol_id. It points at a definition the platform can act on:
resolve to a name, link to in the app, simulate, or convert to a cycler file.
The dict is unvalidated text, so two runs of the same test can spell it
differently and nothing reconciles them.
Use the protocol dict when you have no full protocol. That is common and
not a failure: data imported from a cycler export often records “1C discharge at
25 °C” and nothing reconstructable into an executable definition. Recording what
you know beats dropping it.
Setting both is the best record — protocol_id for what the run was supposed
to execute, the dict for the conditions it actually ran under. One protocol
serves many runs at different temperatures, and only the dict captures which.
When you set
protocol_id, do not put a name in the protocol dict. The
protocol already has one, the two can disagree, and the app suppresses the
dict’s name once protocol_id is set.protocol_id can also be attached later, once the protocol a run executed is
known, via client.cell_measurement.update().
Time series
Time series is the default measurement type. It carries high-resolution cycling data and auto-generates step and cycle summaries on upload. The time series DataFrame must follow the data format — recognized columns includeTime [s], Voltage [V], Current [A], Step count, and
Cycle count.
create() returns a MeasurementBundle containing the measurement record plus
metadata like steps_created. See uploading data for the
full upload workflow — protocol and test-setup metadata, on-machine validation,
and idempotent create_or_get — and reading data to fetch a
measurement back with its full time series, steps, and cycles.
Properties
Properties measurements store key-value pairs directly in the record — no file upload. Use them for manual or one-off measurements like thickness, weight, or internal resistance. Properties-specific fields:protocol, test_setup,
start_time, notes) alongside the properties.
create_properties returns a Measurement directly, not a MeasurementBundle.
Properties measurements have no steps or file uploads, so the bundle wrapper
isn’t needed.File
File measurements attach files (images, PDFs, numpy arrays, or any other file type) to a measurement record. Useful for microscopy images, SEM photos, X-ray CT scans, or post-mortem analysis documents. File-specific fields:File measurements use a signed URL upload flow internally. The client handles
the multi-step process (initiate, upload, confirm) automatically.
Previewing files in Studio
When you open a file measurement in Studio, attached files are shown as a gallery beneath the measurement details:- Images (
.png,.jpg,.webp, etc.) render as inline thumbnails. Click a thumbnail to open it in a full-screen lightbox. - Non-image files (PDFs, numpy arrays, CSVs, etc.) appear as cards with a download button.
Tags
Tags are free-form labels on a measurement, such asbaseline, rpt, or
batch-7, that you can filter, bulk-edit, and search by. Any measurement type
can carry them. Tags belong to a project: suggestions and filters only see the
tags used in that project.
Tags match case-insensitively, and a new tag reuses the project’s existing
spelling, so typing aged when Aged is already in use stores Aged.
Surrounding whitespace is trimmed and duplicates are dropped. Each tag can be
up to 50 characters, and each measurement can carry up to 50 tags.
In the app
- Add tags on a measurement’s detail page, below Notes. Type to search the project’s existing tags, or press Enter to create a new one. Each change saves straight away, and removing a tag offers Undo.
- Bulk-tag from the measurements list: select rows, or use Select all N matching, then choose Edit tags to add or remove tags across the selection.
- Filter by clicking a tag chip in the Tags column, or with the tag filter, which matches measurements carrying any or all of the chosen tags.
- Search for a tag in global search to find the measurements carrying it.
In the API
Passtags when creating a measurement, or in a PATCH to
/cell_measurements/{id}; a PATCH replaces the whole set. List endpoints
accept repeatable tags_all (carries every tag) and tags_any (carries at
least one) filters. GET /cell_measurements/tags?project_id=... lists a
project’s tags with usage counts, most used first, and
POST /cell_measurements/tags/bulk adds or removes tags on up to 1000
measurements at once.
list() for a single cell instance accepts the same tags_all / tags_any
filters, and client.cell_measurement.update(measurement_id, {"tags": [...]})
replaces a measurement’s tags.
Next steps
Uploading data
End-to-end upload workflow: specs, instances, and measurements.
Reading data
List, filter, and retrieve measurements with their full data.