ionworks-api Python package
provides a programmatic interface for managing resources, running simulations,
submitting pipelines, and uploading data in Ionworks Studio.
Installation
Install the package from the repository:Authentication
Get your API key from the Ionworks account settings and configure it:Starting in
ionworks-api 0.10.0, importing ionworks no longer
auto-loads a .env file. Set IONWORKS_API_KEY in your shell
environment, load the .env file yourself (for example with
python-dotenv) before
constructing the client, or pass api_key= explicitly to Ionworks(...).Verify your API key
Useclient.whoami() to confirm which user and organization the configured
API key resolves to. This is the recommended way to debug 401/403 errors,
or to check why you’re seeing data from the wrong organization.
authorized_organization— the org this request is authorized as. For SDK calls, this is the org the configured API key was issued for, and is the source of truth for permission checks on every request the client makes. It’sNoneif no org context could be resolved.organizations— the user’s full membership list (every org they belong to). This is a different question and is not what permission checks run against.
id or name in authorized_organization doesn’t match what you
expect, the wrong key is in use — regenerate one for the correct org from
your account settings.
Default project
Most sub-clients (pipelines, studies, optimizations, cell specifications, …) operate within a project. Rather than threading aproject_id through every call, you can configure a default once
on the client. Sub-client methods that take a project_id argument fall back
to this default when one isn’t passed explicitly.
The client resolves the default in this order:
- The
project_id=argument passed toIonworks(...). - The
IONWORKS_PROJECT_IDenvironment variable. - Otherwise, no default is set — methods that need a project will raise
ValueErrorunlessproject_idis passed at the call site.
https://app.ionworks.com/dashboard/projects/<project-id>/settings.
The
PROJECT_ID environment variable is still accepted for backwards
compatibility but is deprecated. Set IONWORKS_PROJECT_ID instead — using
the old name emits a DeprecationWarning and will stop working in a future
release.Environment variables
The client reads the following variables from your shell environment when constructed..env files are not loaded automatically — populate the
environment yourself (for example by sourcing the file, or by calling
python-dotenv) before
constructing the client.
DataFrame backend
By default, the client returns data as polars DataFrames. You can switch to pandas if your workflow requires it.Timeout and retry behavior
The client automatically retries failed requests on connection errors, timeouts, and server errors (5xx). By default:- Requests time out after 10 seconds
- Failed requests retry up to 5 times with exponential backoff
- Dropped connections (the server closed the socket before the request reached the application — common on reused keep-alive connections) are retried for all methods, including POST and PATCH. The request never reached the server, so resending is safe.
- Read timeouts and 5xx responses are only retried for idempotent methods (GET and DELETE). The server may have already processed a POST or PATCH, so resubmitting could duplicate the operation.
Sub-clients
TheIonworks client exposes domain-specific sub-clients:
Discovering the API
client.capabilities() and client.schema(name) return the same content
the discover-api agent skill is built on. Use them from a
notebook or script to introduce yourself — or a coding agent you’re
scripting against — to the platform’s data hierarchy and to fetch the
authoritative JSON Schemas for measurements and UCP protocols.
capabilities() also returns pointers to the OpenAPI spec
(/openapi.json) and per-resource JSON Schema endpoints under
caps["schemas"], so agents can fetch the exact shape of any create/update
payload before calling it.
Web app URL helpers
client.urls builds links to resource pages in the Ionworks web app
(Ionworks Studio) without requiring you to hand-construct URLs from entity
IDs. Use it to surface clickable links from notebooks, scripts, dashboards,
or Slack/email reports so collaborators can jump straight to the resource in
the web app.
Every helper runs entirely locally — no network call — except
client.urls.simulation(), which fetches the simulation once when
parameterized_model_id isn’t supplied (see below).
project_id is optional — it falls back to the
default project configured on the client.
Simulation URLs
A simulation’s web-app route is nested under its parameterized model. If you already know theparameterized_model_id, pass it in to avoid a network
call:
parameterized_model_id (e.g. a study-only
simulation), the helper raises ValueError and you must pass the parent
explicitly.
Canceling jobs
You can cancel running jobs (simulations, pipelines, and optimizations) using the Python API. Each job has a unique ID that you can use to cancel it.Resubmitting a failed pipeline
If a pipeline stops because its first failed element could not be submitted (error_code = SUBMISSION_FAILED), you can resubmit it without rebuilding the
configuration. Completed elements are preserved; execution resumes from the
failed element.
The Python client does not yet expose a resubmit method, so call the REST
endpoint directly as a temporary workaround. Resubmission goes through the
generic jobs endpoint, and a pipeline is identified by its job ID — the same
ID you pass to client.pipeline.get(...):
SUBMISSION_FAILED errors. For execution
timeouts or configuration mistakes, create a new pipeline with the corrected
configuration. For internal errors, wait briefly and create a new pipeline if
the issue persists. See Handling pipeline
failures for details.
Retrieving job metadata
Standard job-detail responses strip fields that can grow large — submitted configs, full result payloads, and serialized PyBaMM models — so listing and polling stay fast even for pipelines or optimizations with heavy inline data. When you actually need those fields, fetch them withclient.job.get_metadata:
- Re-run a job from its original submitted config without keeping a local copy.
- Audit the exact inputs that produced a result.
- Read large result blobs — for example, optimization traces, or the
validation_resultsandvalidation_plot_configproduced by pipeline validations — that aren’t included in the default job response.
dict parsed from the job’s
metadata.json.gz blob. If a job has no metadata file (for example, it
failed before writing one) the call raises an error — wrap it in a
try/except if you’re iterating over many jobs.