Skip to main content
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:
pip install ionworks-api

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:
  1. The project_id= argument passed to Ionworks(...).
  2. The IONWORKS_PROJECT_ID environment variable.
  3. 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.
VariableRequiredDefaultDescription
IONWORKS_API_KEYYesAPI key from your account settings.
IONWORKS_API_URLNohttps://api.ionworks.comAPI base URL.
IONWORKS_PROJECT_IDFor project-scoped callsDefault project ID for sub-client methods.
IONWORKS_DATAFRAME_BACKENDNopolarsDataFrame 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-clientAccessDocumentation
Projectsclient.projectCore Concepts API
Modelsclient.modelBuild API
Parameterized modelsclient.parameterized_modelBuild API
Studiesclient.studySimulate API
Protocolsclient.protocolSimulate API
Simulationsclient.simulationSimulate API
Pipelinesclient.pipelineSimulate API
Simple pipelinesclient.simple_pipelineSimulate API
Optimizationsclient.optimizationOptimize API
Cell specificationsclient.cell_specUploading data
Cell instancesclient.cell_instanceUploading data
Cell measurementsclient.cell_measurementMeasurements
Jobsclient.jobCanceling 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.