---
title: "List Dynamic V1"
method: GET
path: "/v1/dynamic-simulations"
tags: ["v1", "dynamic-simulations"]
---

# List Dynamic V1

`GET /v1/dynamic-simulations`

## Request

- Base URL: `https://thrustlab.com`
- URL: `https://thrustlab.com/v1/dynamic-simulations`
- Auth: HTTP bearer

List the caller's dynamic simulations (cursor-paginated, newest first).

Mirrors ``GET /v1/sweeps`` so the project page + queue strip can surface
dynamic runs alongside steady/sweep runs. Ownership-scoped via the project
join (a caller never sees another user's runs). ``project`` accepts a raw
UUID or proj_<ksuid>; the cursor is ``{created_at.isoformat()}|{public_id}``.

## Query parameters

- `project` string, nullable
- `cursor` string, nullable
- `limit` integer

## Response `200`

Successful Response

- DynamicListResponse: Cursor-paginated list of dynamic simulations (mirrors SweepListResponse) so the project page + queue strip can surface dynamic runs like steady/sweep runs.
  - `data` DynamicResource[], required
    - `battery_topology` object, nullable
    - `cancel_requested_at` string, nullable: When a cancel was requested for a RUNNING run. The status stays `running` until the worker stops at its next integration chunk boundary — at which point it keeps the results it has, refunds in full, and the run turns `canceled` with a partial `result`. Null when no cancel is pending, which includes every terminal run: the field reports a request in flight, not the history of one. A QUEUED run cancels immediately instead and never sets this.
    - `created_at` string, nullable: When the run was submitted.
    - `credits_cost` integer, required
    - `dispatched_at` string, nullable: When the run was handed to the worker queue. A dynamic run is dispatched at creation, so this always equals created_at — it is NOT the start of execution.
    - `display_labels` object, nullable
    - `error` object, nullable
    - `id` string, required
    - `input_snapshot` object, nullable
    - `is_starred` boolean
    - `name` string, nullable
    - `object` 'dynamic_simulation'
    - `progress` object, nullable: How far a running solve has got, refreshed at every integration chunk boundary: `fraction` (0-1, null when it cannot be estimated), `sim_time_s` reached, `sim_time_total_s` (null for a run to depletion, which has no fixed horizon — its fraction comes from the estimated duration and is capped at 0.99), `wall_s` of real time so far, and `updated_at`. Null before the first chunk completes.
    - `project_id` string, required
    - `result` object, nullable
    - `snapshot_version` integer
    - `solver_engine` string
    - `started_at` string, nullable: When a worker claimed the run and the solve began. Null until then. For a dynamic run this is the only field that shows how long it waited for a slot.
    - `status` 'queued' | 'running' | 'completed' | 'failed' | 'canceled', required
  - `has_more` boolean
  - `next_cursor` string, nullable
  - `object` 'list'

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/thrustlab/apis/thrustlab-api.md) · [All operations](https://skmtc.dev/thrustlab/apis/thrustlab-api/llms.txt) · [OpenAPI document](https://skmtc.dev/thrustlab/apis/thrustlab-api/revisions/c19717e52529?raw)
