The ionworks-api Python package
provides a programmatic interface for managing resources, running simulations,
submitting pipelines, and uploading data in Ionworks Studio.
Driving Ionworks from a coding agent? The
Ionworks Agentic Toolkit ships SDK-aware skills for Claude Code,
Codex, and other agents — including an install skill that runs through
this page’s setup for you.
Installation
Install the package from the repository:
Authentication
Get your API key from the Ionworks account settings and configure it:
from ionworks import Ionworks
# Option 1: Environment variable (recommended)
# Set IONWORKS_API_KEY in your environment or .env file
client = Ionworks()
# Option 2: Direct configuration
client = Ionworks(api_key="your_key")
# Option 3: Custom timeout and retry settings
client = Ionworks(
timeout=30, # Request timeout in seconds (default: 10)
max_retries=3 # Max retries on failure (default: 5)
)
Never commit API keys to version control. Use environment variables or a
.env file for credential management.
Verify your API key
Use client.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.
me = client.whoami()
print(me["email"], me["authorized_organization"])
# [email protected] {'id': 'org_abc123', 'name': 'Acme Battery'}
The response has two organization fields and the distinction matters:
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’s None if 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.
If the 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 a project_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 to Ionworks(...).
- The
IONWORKS_PROJECT_ID environment variable.
- Otherwise, no default is set — methods that need a project will raise
ValueError unless project_id is passed at the call site.
# Option 1: Environment variable (recommended)
# Set IONWORKS_PROJECT_ID in your environment or .env file
client = Ionworks()
# Option 2: Pass to the client constructor
client = Ionworks(project_id="your-project-id")
# Override on a per-call basis when needed
client.study.list(project_id="other-project-id")
You can find your project ID in the URL of the project settings page:
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 loads .env files automatically via
python-dotenv.
| Variable | Required | Default | Description |
|---|
IONWORKS_API_KEY | Yes | — | API key from your account settings. |
IONWORKS_API_URL | No | https://api.ionworks.com | API base URL. |
IONWORKS_PROJECT_ID | For project-scoped calls | — | Default project ID for sub-client methods. |
IONWORKS_DATAFRAME_BACKEND | No | polars | DataFrame backend: polars or pandas. |
DataFrame backend
By default, the client returns data as polars DataFrames. You can
switch to pandas if your workflow requires it.
# Option 1: Set via constructor
client = Ionworks(dataframe_backend="pandas")
# Option 2: Set via environment variable
# IONWORKS_DATAFRAME_BACKEND=pandas
# Option 3: Set at runtime
from ionworks import set_dataframe_backend, get_dataframe_backend
set_dataframe_backend("pandas")
print(get_dataframe_backend()) # "pandas"
All methods that return DataFrames (time series, steps, cycles) respect this setting.
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
- Only GET and DELETE requests are retried. POST and PATCH requests are not retried to prevent duplicate operations.
You can customize these settings:
# Longer timeout for large uploads
client = Ionworks(timeout=60)
# Disable retries
client = Ionworks(max_retries=0)
Sub-clients
The Ionworks client exposes domain-specific sub-clients:
| Sub-client | Access | Documentation |
|---|
| Projects | client.project | Core Concepts API |
| Models | client.model | Build API |
| Parameterized models | client.parameterized_model | Build API |
| Studies | client.study | Simulate API |
| Protocols | client.protocol | Simulate API |
| Simulations | client.simulation | Simulate API |
| Pipelines | client.pipeline | Simulate API |
| Simple pipelines | client.simple_pipeline | Simulate API |
| Optimizations | client.optimization | Optimize API |
| Cell specifications | client.cell_spec | Uploading data |
| Cell instances | client.cell_instance | Uploading data |
| Cell measurements | client.cell_measurement | Measurements |
| Jobs | client.job | Canceling jobs |
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.
# Cancel a job by ID
client.job.cancel(job_id="job_abc123")
Cancelling a parent job automatically cancels all of its child jobs. For
example, cancelling a pipeline cancels all of its running elements.