> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paradime.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Bolt

> Manage Bolt schedules and runs from Python: list schedules, trigger and cancel runs, inspect status, and fetch dbt™ artifacts with the paradime-io SDK.

<Info>
  **Prerequisites:**

  * This feature is available with the [**Paradime Bolt plan**](https://www.paradime.io/pricing)**.**
  * Your API keys ***must*** have either Bolt Schedules Admin or Bolt Schedules Metadata Viewer capabilities.
</Info>

<Info>
  These examples authenticate with an **account API key** (`api_secret="prdm_cmp_..."` plus `workspace_uid`), which requires `paradime-io` 6.0.0 or later. Legacy **workspace API keys** (`api_key` + `api_secret`) are still supported. See Getting Started.
</Info>

The Bolt module allows you to easily manage and control Bolt schedules and runs within your workspace.

It provides tools to create, configure, and monitor schedules, automate tasks, and access detailed logs and reports.

<Warning>
  **Schedules are identified by slug.** Every Bolt method that targets a schedule accepts a `slug=` keyword argument — the identifier returned by `create_schedule` (and shown in the Bolt UI).
</Warning>

### List Bolt schedules

Get a list of Bolt schedules. The list is paginated. The total count of schedules is also returned.

<ParamField path="offset" type="int" default="0">
  The offset value for pagination.
</ParamField>

<ParamField path="limit" type="int" default="100">
  The limit value for pagination.
</ParamField>

<ParamField path="show_inactive" type="bool" default="False">
  Flag to indicate whether to return inactive schedules instead of active schedules.
</ParamField>

<ParamField path="suspended" type="Optional[bool]" default="None">
  Filter by paused (suspended) state. Leave as `None` to return all schedules, pass `True` for only paused schedules, or `False` for only active (non-paused) schedules.
</ParamField>

<ResponseField name="Returns" type="BoltSchedules">
  An object containing the list of Bolt schedules and the total count of schedules.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# List all schedules
schedules = paradime.bolt.list_schedules().schedules
```

### Get latest runs for a schedule

<ParamField path="slug" type="str" required>
  The schedule slug returned by `create_schedule`. Preferred over `schedule_name`.
</ParamField>

<ParamField path="schedule_name" type="str">
  *Deprecated alias for `slug`.* Still accepted for backwards compatibility — emits a `DeprecationWarning`. Exactly one of `slug` or `schedule_name` must be provided.
</ParamField>

<ParamField path="offset" type="int" default="0">
  The offset value for pagination. Must be >= 0.
</ParamField>

<ParamField path="limit" type="int" default="50">
  The limit value for pagination. Must be between 1 and 1000.
</ParamField>

<ResponseField name="Returns" type="BoltScheduleRuns">
  An object containing the list of Bolt runs with details like ID, status, actor, timestamps, and git information.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Get the latest 10 runs for a schedule
recent_runs = paradime.bolt.list_runs(
    slug="flowing-pachy-wyy4fs",
    offset=0,
    limit=10
)

# Access the runs and metadata
for run in recent_runs.runs:
    print(f"Run ID: {run.id}")
    print(f"Status: {run.state}")
    print(f"Started: {run.start_dttm}")
    print(f"Actor: {run.actor}")
    if run.git_info.branch:
        print(f"Branch: {run.git_info.branch}")
    if run.git_info.pull_request_id:
        print(f"PR: {run.git_info.pull_request_id}")
    print("---")

# Get runs with pagination (next page)
next_runs = paradime.bolt.list_runs(
    slug="flowing-pachy-wyy4fs",
    offset=10,
    limit=10
)

# Get all recent runs (up to 100)
all_recent_runs = paradime.bolt.list_runs(
    slug="flowing-pachy-wyy4fs",
    limit=100
)
```

### Create a Bolt schedule

Create a new Bolt schedule and get back its slug. The slug is the identifier you pass as `slug=` to every other Bolt method (`trigger_run`, `get_schedule`, `delete_schedule`, etc.).

<ParamField path="name" type="str" required>
  Human-readable schedule name shown in the Bolt UI.
</ParamField>

<ParamField path="schedule" type="str" required>
  Cron expression (e.g. `"0 1 * * *"`) or the literal `"OFF"` for manual-only runs.
</ParamField>

<ParamField path="environment" type="str" required>
  Name of the environment to run in (e.g. `"production"`).
</ParamField>

<ParamField path="commands" type="List[str]" required>
  Commands the schedule should run, in order (e.g. `["dbt run", "dbt test"]`).
</ParamField>

<ParamField path="git_branch" type="Optional[str]">
  Git branch the run should check out. Defaults to the environment's branch.
</ParamField>

<ParamField path="description" type="Optional[str]">
  Free-text description shown in the UI.
</ParamField>

<ParamField path="timezone" type="Optional[str]">
  IANA timezone for the cron expression (e.g. `"UTC"`, `"Europe/London"`).
</ParamField>

<ParamField path="owner_email" type="Optional[str]">
  Email of the workspace member who should own the schedule.
</ParamField>

<ParamField path="suspended" type="Optional[bool]">
  Create the schedule already suspended. Defaults to active.
</ParamField>

<ParamField path="sla_seconds" type="Optional[int]">
  Soft SLA window in seconds; runs exceeding this are surfaced as overdue.
</ParamField>

<ParamField path="trigger_on_merge" type="Optional[bool]">
  If `True`, run on every merge to `git_branch`.
</ParamField>

<ParamField path="notifications" type="Optional[BoltNotificationsInput | dict]">
  Slack / Teams / email notification routing.
</ParamField>

<ParamField path="integrations" type="Optional[BoltIntegrationsInput | dict]">
  PagerDuty / Datadog / incident.io / New Relic incident triggers fired on failures.
</ParamField>

<ParamField path="self_healing" type="Optional[BoltSelfHealingConfigInput | dict]">
  Paradime self-healing agent (auto-retry + Slack updates).
</ParamField>

<ParamField path="turbo_ci" type="Optional[BoltDeferredScheduleConfigInput | dict]">
  Turbo CI config — defer state from another schedule's last successful run.
</ParamField>

<ParamField path="deferred_schedule" type="Optional[BoltDeferredScheduleConfigInput | dict]">
  Slim-CI-style deferred schedule config.
</ParamField>

<ParamField path="schedule_trigger" type="Optional[BoltScheduleTriggerInput | dict]">
  Run this schedule when a parent schedule (possibly in another workspace) finishes.
</ParamField>

<ParamField path="env_vars" type="Optional[List[BoltEnvironmentVariableInput | dict]]">
  Environment-variable overrides for this schedule.
</ParamField>

<ResponseField name="Returns" type="str">
  The slug assigned by the backend. Pass this value as `slug=` to every other Bolt method.
</ResponseField>

<Warning>
  There is a short consistency window (\~10s) between schedule creation and the trigger path accepting the new slug. Callers that immediately invoke `trigger_run` on a brand-new slug may need to retry for a few seconds.
</Warning>

### **Create a minimal schedule**

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Create a manual-only schedule and capture its slug
slug = paradime.bolt.create_schedule(
    name="Nightly build",
    schedule="OFF",
    environment="production",
    commands=["dbt build"],
)
print(f"created schedule slug: {slug}")
```

### **Create a schedule with notifications, env vars, and self-healing**

```python theme={"system"}
# First party modules
from paradime import Paradime
from paradime.apis.bolt.types import (
    BoltNotificationsInput,
    BoltNotificationChannelInput,
    BoltSelfHealingConfigInput,
    BoltEnvironmentVariableInput,
)

paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

slug = paradime.bolt.create_schedule(
    name="Nightly build",
    schedule="0 1 * * *",
    environment="production",
    commands=["dbt build"],
    git_branch="main",
    description="Nightly run of the production warehouse build.",
    timezone="UTC",
    notifications=BoltNotificationsInput(
        slack_notifications=[
            BoltNotificationChannelInput(channel="#data-alerts", events=["failed"]),
        ],
        email_notifications=[
            BoltNotificationChannelInput(channel="ops@example.com", events=["failed", "passed"]),
        ],
    ),
    self_healing=BoltSelfHealingConfigInput(enabled=True, slack_channel="#data-alerts"),
    env_vars=[
        BoltEnvironmentVariableInput(key="DBT_PROFILES_DIR", value="/workspace/profiles"),
        BoltEnvironmentVariableInput(key="DBT_TARGET", value="prod"),
    ],
)
```

### **Create a schedule using raw dicts (escape hatch)**

Every nested input also accepts a plain dict that matches the GraphQL shape. Useful when you want to set a field that isn't yet modelled as a typed input.

```python theme={"system"}
# First party modules
from paradime import Paradime

paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

slug = paradime.bolt.create_schedule(
    name="Nightly build",
    schedule="OFF",
    environment="production",
    commands=["dbt build"],
    notifications={
        "slackNotifications": [
            {"channel": "#data-alerts", "events": ["failed"]},
        ],
    },
    env_vars=[{"key": "DBT_TARGET", "value": "prod"}],
)
```

### Delete a Bolt schedule

Delete a Bolt schedule by slug. Schedules defined in YAML cannot be deleted via the API — remove them from the repository instead.

<ParamField path="slug" type="str" required>
  The schedule slug returned by `create_schedule` (also shown in the Bolt UI).
</ParamField>

<ResponseField name="Returns" type="None">
  This method returns nothing.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the slug of the schedule to delete
BOLT_SCHEDULE_SLUG = "nightly-build-a1b2c3"

paradime.bolt.delete_schedule(BOLT_SCHEDULE_SLUG)
```

### Get a Bolt schedule

Retrieves information about a specific schedule.

<ParamField path="slug" type="str" required>
  The schedule slug returned by `create_schedule`. Preferred over `schedule_name`.
</ParamField>

<ParamField path="schedule_name" type="str">
  *Deprecated alias for `slug`.* Still accepted for backwards compatibility, emits a `DeprecationWarning`. Exactly one of `slug` or `schedule_name` must be provided.
</ParamField>

<ResponseField name="Returns" type="BoltScheduleInfo">
  An object containing information about the schedule (commands, cron expression, owner, source, latest run ID, and suspended state).
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Get details for a schedule
schedule_info = paradime.bolt.get_schedule(slug="flowing-pachy-wyy4fs")

print(schedule_info.commands)
print(schedule_info.schedule)
print(schedule_info.latest_run_id)
```

### Suspend or resume a Bolt schedule

Suspends or resumes a schedule created via the UI or API.

<Info>
  This only works for schedules created via the UI or API, not via YAML.
</Info>

<ParamField path="suspend" type="bool" required>
  `True` to suspend (pause) the schedule, `False` to resume it.
</ParamField>

<ParamField path="slug" type="str" required>
  The schedule slug returned by `create_schedule`. Preferred over `schedule_name`.
</ParamField>

<ParamField path="schedule_name" type="str">
  *Deprecated alias for `slug`.* Still accepted for backwards compatibility, emits a `DeprecationWarning`. Exactly one of `slug` or `schedule_name` must be provided.
</ParamField>

<ResponseField name="Returns" type="None">
  This method returns nothing.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Pause a schedule
paradime.bolt.suspend_schedule(slug="flowing-pachy-wyy4fs", suspend=True)

# Resume it later
paradime.bolt.suspend_schedule(slug="flowing-pachy-wyy4fs", suspend=False)
```

### List all schedule names

List schedule names across all workspaces in the company. Unlike `list_schedules` (scoped to the API key's workspace), this returns schedules in every workspace, so `schedule_trigger` references that point at another workspace can be validated.

<ResponseField name="Returns" type="List[Tuple[str, str]]">
  A list of `(workspace_name, schedule_name)` tuples.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# List every schedule across all workspaces
for workspace_name, schedule_name in paradime.bolt.list_all_schedule_names():
    print(f"{workspace_name}: {schedule_name}")
```

### Create schedule slugs

Mint slugs for a list of display names via the backend.

<ParamField path="display_names" type="List[str]" required>
  Human-readable schedule names to mint slugs for.
</ParamField>

<ResponseField name="Returns" type="List[str]">
  List of minted slugs in the same order as the input display names.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Mint slugs for a set of display names
slugs = paradime.bolt.create_schedule_slugs(["Nightly build", "Hourly refresh"])
```

### Triggering a Bolt run

Triggers a run for a given schedule slug.

<ParamField path="slug" type="str" required>
  The schedule slug to trigger the run for. Preferred over `schedule_name`.
</ParamField>

<ParamField path="schedule_name" type="str">
  *Deprecated alias for `slug`.* Still accepted for backwards compatibility — emits a `DeprecationWarning`. Exactly one of `slug` or `schedule_name` must be provided.
</ParamField>

<ParamField path="commands" type="Optional[List[str]]">
  The list of commands to execute in the run. This will override the commands defined in the schedule. Defaults to *None*.
</ParamField>

<ParamField path="branch" type="Optional[str]">
  The branch or commit hash to run the commands on. Defaults to None.
</ParamField>

<ParamField path="pr_number" type="Optional[int]">
  The pull request number to associate with the run. Defaults to None.
</ParamField>

<ParamField path="reason" type="Optional[str]">
  A freeform reason/label describing why or from where the run was triggered (e.g. the application that made the call). Stored with the run for context and auditing. Defaults to None.
</ParamField>

<ResponseField name="Returns" type="int">
  The ID of the triggered run.
</ResponseField>

### **Trigger a run with default commands and branch**

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the Bolt schedule slug to trigger
BOLT_SCHEDULE_SLUG = "flowing-pachy-wyy4fs"

# Trigger a run of the Bolt schedule and get the run ID
run_id = paradime.bolt.trigger_run(slug=BOLT_SCHEDULE_SLUG)

# Get the run status
run_status = paradime.bolt.get_run_status(run_id)
```

### **Trigger a run with a custom git branch and PR Number**

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the Bolt schedule slug to trigger
BOLT_SCHEDULE_SLUG = "flowing-pachy-wyy4fs"

# Replace with the branch name or commit hash
GIT_BRANCH = "feature-branch-123"

# Replace with the PR number to associate with the run (optional)
PR_NUMBER = 123

# Trigger a run of the Bolt schedule and get the run ID
run_id = paradime.bolt.trigger_run(slug=BOLT_SCHEDULE_SLUG, branch=GIT_BRANCH, pr_number=PR_NUMBER)

# Get the run status
run_status = paradime.bolt.get_run_status(run_id)
```

### **Trigger a run with custom commands**

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the Bolt schedule slug to trigger
BOLT_SCHEDULE_SLUG = "flowing-pachy-wyy4fs"

# Replace with the commands to execute in the run
COMMANDS_OVERRIDE = ["dbt run --select order_items", "dbt test"]

# Trigger a run of the Bolt schedule and get the run ID
run_id = paradime.bolt.trigger_run(slug=BOLT_SCHEDULE_SLUG, commands=COMMANDS_OVERRIDE)

# Get the run status
run_status = paradime.bolt.get_run_status(run_id)
```

### **Trigger a run with a custom git branch**

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the Bolt schedule slug to trigger
BOLT_SCHEDULE_SLUG = "flowing-pachy-wyy4fs"

# Replace with the branch name or commit hash
GIT_BRANCH = "feature-branch-123"

# Trigger a run of the Bolt schedule and get the run ID
run_id = paradime.bolt.trigger_run(slug=BOLT_SCHEDULE_SLUG, branch=GIT_BRANCH)

# Get the run status
run_status = paradime.bolt.get_run_status(run_id)
```

### **Trigger a run with a reason**

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the Bolt schedule slug to trigger
BOLT_SCHEDULE_SLUG = "flowing-pachy-wyy4fs"

# A freeform label describing why or from where the run was triggered
REASON = "triggered by data-quality-bot"

# Trigger a run of the Bolt schedule and get the run ID
run_id = paradime.bolt.trigger_run(slug=BOLT_SCHEDULE_SLUG, reason=REASON)

# Get the run status
run_status = paradime.bolt.get_run_status(run_id)
```

### Retrying a Bolt run

**Retry the latest failed run of a schedule by slug**

Retries the **latest failed run** of a Bolt schedule by slug, without needing to know its run ID. Resumes from the failed command of the most recent run of the given schedule. The first failed dbt command is substituted with `dbt retry` when supported. Infrastructure commands (`git clone`, `dbt deps`) are skipped.

A new Bolt run is created; the original run is unchanged.

<ParamField path="slug" type="str" required>
  The schedule slug whose latest failed run to retry. Preferred over `schedule_name`.
</ParamField>

<ParamField path="schedule_name" type="str">
  *Deprecated alias for `slug`.* Still accepted for backwards compatibility — emits a `DeprecationWarning`. Exactly one of `slug` or `schedule_name` must be provided.
</ParamField>

<ResponseField name="Returns" type="int">
  The ID of the newly created retry run.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the slug of the schedule to retry
BOLT_SCHEDULE_SLUG = "flowing-pachy-wyy4fs"

# Retry the latest failed run; returns the new run ID
new_run_id = paradime.bolt.retry_schedule_from_failure(slug=BOLT_SCHEDULE_SLUG)

# Poll the new run like any other Bolt run
new_run_status = paradime.bolt.get_run_status(new_run_id)
```

### **Retry only failed commands by Run ID**

Retries a failed Bolt run by re-running **only the failed commands**. The first failed dbt command is substituted with `dbt retry` when supported, so only the failed models are re-executed. Infrastructure commands (`git clone`, `dbt deps`) are skipped.

A new Bolt run is created; the original run is unchanged.

<ParamField path="run_id" type="int" required>
  The ID of the failed run to retry.
</ParamField>

<ResponseField name="Returns" type="int">
  The ID of the newly created retry run.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the run ID of the failed Bolt run to retry
FAILED_BOLT_RUN_ID = 1

# Retry only the failed commands; returns the new run ID
new_run_id = paradime.bolt.retry_run(run_id=FAILED_BOLT_RUN_ID)

# Poll the new run like any other Bolt run
new_run_status = paradime.bolt.get_run_status(new_run_id)
```

### **Retry all commands by Run ID**

Retries a Bolt run by re-running **every** original command verbatim, regardless of which ones succeeded or failed. Infrastructure commands (`git clone`, `dbt deps`) are excluded.

A new Bolt run is created; the original run is unchanged.

<ParamField path="run_id" type="int" required>
  The ID of the run to retry.
</ParamField>

<ResponseField name="Returns" type="int">
  The ID of the newly created retry run.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the run ID of the Bolt run to retry
BOLT_RUN_ID = 1

# Re-run all original commands; returns the new run ID
new_run_id = paradime.bolt.retry_run_all(run_id=BOLT_RUN_ID)

# Poll the new run like any other Bolt run
new_run_status = paradime.bolt.get_run_status(new_run_id)
```

### Streaming logs from a Bolt command

Tail the stdout and stderr of a Bolt command **while it is still running**, instead of waiting for the run to finish and reading the final logs. Two methods are available:

* `stream_command_logs(command_id)` — a generator that yields lines as they arrive and stops automatically when the command finishes. Use this for live tailing.
* `get_command_logs(command_id, cursor)` — a single batch fetch using an opaque cursor. Use this when you need finer control over polling cadence or want to interleave log polling with other work.

Both methods return `BoltLogLine` objects with a `stream` field (`BoltLogStream.STDOUT` or `BoltLogStream.STDERR`) and a `line` field (the raw log line).

<Info>
  To get a `command_id`, list the commands for a run with `paradime.bolt.list_run_commands(run_id)`.
</Info>

### **Stream logs until the command finishes**

`stream_command_logs` polls until the command exits and yields each line as it arrives.

<ParamField path="command_id" type="int" required>
  The ID of the Bolt command to stream logs from.
</ParamField>

<ParamField path="poll_interval" type="float" default="2.0">
  Seconds to wait between empty polls.
</ParamField>

<ResponseField name="Yields" type="Iterator[BoltLogLine]">
  Each log line in arrival order within a poll batch. Stdout lines for the batch precede stderr lines (approximate interleaving — true cross-stream ordering is not recorded).
</ResponseField>

```python theme={"system"}
# Standard library modules
import os
import time

# First party modules
from paradime import Paradime
from paradime.apis.bolt.types import BoltLogStream, BoltRunState

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Trigger a run
run_id = paradime.bolt.trigger_run(slug="flowing-pachy-wyy4fs")

# Tail each command as it appears, until the run finishes
seen_command_ids: set[int] = set()
while True:
    for cmd in paradime.bolt.list_run_commands(run_id):
        if cmd.id in seen_command_ids:
            continue
        seen_command_ids.add(cmd.id)
        print(f"\n--- Command {cmd.id}: {cmd.command} ---")
        for log_line in paradime.bolt.stream_command_logs(cmd.id):
            prefix = "stderr" if log_line.stream is BoltLogStream.STDERR else "stdout"
            print(f"[{prefix}] {log_line.line}", end="")

    if paradime.bolt.get_run_status(run_id) is not BoltRunState.RUNNING:
        break
    time.sleep(2)

```

### **One-shot polling with a cursor**

`get_command_logs` returns a single batch with an opaque cursor and a `finished` flag. Pass the cursor back into the next call to fetch only new lines.

<ParamField path="command_id" type="int" required>
  The ID of the Bolt command.
</ParamField>

<ParamField path="cursor" type="str" default="0:0">
  Opaque cursor returned by the previous call. *Use the default* `"0:0"` *on the first call to fetch from the beginning.*
</ParamField>

<ResponseField name="Returns" type="BoltCommandLogs">
  An object with `lines` (`List[BoltLogLine]`), `cursor` (str — pass to the next call), and `finished` (bool — flips to `True` once the command exits).
</ResponseField>

```python theme={"system"}
# First party modules
import time
from paradime import Paradime

paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

COMMAND_ID = 59241
cursor = "0:0"

while True:
    batch = paradime.bolt.get_command_logs(COMMAND_ID, cursor=cursor)

    for log_line in batch.lines:
        print(log_line.line, end="")

    if batch.finished:
        break

    cursor = batch.cursor
    if not batch.lines:
        time.sleep(2)
```

### Cancelling a Bolt run

Cancels a Bolt run.

<ParamField path="run_id" type="int" required>
  The ID of the run to cancel.
</ParamField>

<ResponseField name="Returns" type="None">
  This method returns nothing.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the run ID of the Bolt schedule to cancel
BOLT_SCHEDULE_RUN_ID = 1

# Cancel the run
paradime.bolt.cancel_run(run_id=BOLT_SCHEDULE_RUN_ID)
```

### Get the status of a run

Retrieves the status of a run based on the provided run ID.

<ParamField path="run_id" type="int" required>
  The ID of the run.
</ParamField>

<ResponseField name="Returns" type="Optional[BoltRunState]">
  The state of the run.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the run ID to check
BOLT_RUN_ID = 1

run_status = paradime.bolt.get_run_status(run_id=BOLT_RUN_ID)
print(run_status)
```

### List commands for a run

Retrieves the list of command level details for a given run, sorted by command ID.

<ParamField path="run_id" type="int" required>
  The ID of the run.
</ParamField>

<ResponseField name="Returns" type="List[BoltCommand]">
  The list of Bolt commands for the run, sorted by command ID.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the run ID to inspect
BOLT_RUN_ID = 1

for command in paradime.bolt.list_run_commands(run_id=BOLT_RUN_ID):
    print(f"Command {command.id}: {command.command} (return code {command.return_code})")
```

### List artifacts for a command

Retrieves the artifacts associated with a given command.

<Info>
  To get a `command_id`, list the commands for a run with `paradime.bolt.list_run_commands(run_id)`.
</Info>

<ParamField path="command_id" type="int" required>
  The ID of the command.
</ParamField>

<ResponseField name="Returns" type="List[BoltCommandArtifact]">
  A list of `BoltCommandArtifact` objects representing the artifacts, each with an `id` and a `path`.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the command ID to inspect
COMMAND_ID = 59241

for artifact in paradime.bolt.list_command_artifacts(command_id=COMMAND_ID):
    print(f"{artifact.id}: {artifact.path}")
```

### Get an artifact URL

Retrieves the URL of an artifact based on its ID.

<ParamField path="artifact_id" type="int" required>
  The ID of the artifact.
</ParamField>

<ResponseField name="Returns" type="str">
  The URL of the artifact.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the artifact ID
ARTIFACT_ID = 1

artifact_url = paradime.bolt.get_artifact_url(artifact_id=ARTIFACT_ID)
```

### Getting Bolt run artifacts

**Get latest run manifest.json**

Retrieves the latest manifest JSON for a given schedule.

<ParamField path="slug" type="str" required>
  The schedule slug. Preferred over `schedule_name`.
</ParamField>

<ParamField path="schedule_name" type="str">
  *Deprecated alias for `slug`.* Still accepted for backwards compatibility — emits a `DeprecationWarning`. Exactly one of `slug` or `schedule_name` must be provided.
</ParamField>

<ParamField path="command_index" type="Optional[int]">
  The index of the command in the schedule. Defaults to None.
</ParamField>

<ParamField path="max_runs" type="int" default="50">
  The maximum number of latest runs to search through.
</ParamField>

<ResponseField name="Returns" type="dict">
  The content of the latest manifest JSON.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the Bolt schedule slug you want to get artifacts from
BOLT_SCHEDULE_SLUG = "flowing-pachy-wyy4fs"

# Get manifest.json dictionary
manifest_json = paradime.bolt.get_latest_manifest_json(slug=BOLT_SCHEDULE_SLUG)
```

**Get latest run artifacts URL**

Retrieves the URL of the latest artifact for a given schedule.

<ParamField path="slug" type="str" required>
  The schedule slug. Preferred over `schedule_name`.
</ParamField>

<ParamField path="schedule_name" type="str">
  *Deprecated alias for `slug`.* Still accepted for backwards compatibility — emits a `DeprecationWarning`. Exactly one of `slug` or `schedule_name` must be provided.
</ParamField>

<ParamField path="artifact_path" type="str" required>
  The path of the artifact.
</ParamField>

<ParamField path="command_index" type="Optional[int]">
  The index of the command in the schedule. Defaults to searching through all commands from the last command to the first.
</ParamField>

<ParamField path="max_runs" type="int" default="50">
  The maximum number of latest runs to search through.
</ParamField>

<ResponseField name="Returns" type="str">
  The URL of the latest artifact.
</ResponseField>

```python theme={"system"}
# First party modules
from paradime import Paradime

# Create a Paradime client with your API credentials
paradime = Paradime(api_endpoint="API_ENDPOINT", api_secret="prdm_cmp_...", workspace_uid="WORKSPACE_UID")

# Replace with the Bolt schedule slug you want to get artifacts from
BOLT_SCHEDULE_SLUG = "flowing-pachy-wyy4fs"

# Get any artifact
artifact_url = paradime.bolt.get_latest_artifact_url(
    slug=BOLT_SCHEDULE_SLUG, artifact_path="target/catalog.json"
)
```


## Related topics

- [Bolt CLI](/developers/paradime-cli/bolt-cli.md)
- [Bolt API](/developers/graphql-api/api-reference/bolt-api.md)
- [Triggering from Bolt](/products/dino-ai/programmable-agents/triggering-from-bolt.md)
- [The .bolt/ Folder](/products/bolt/creating-schedules/schedules-as-code/modular-schedules-with-the-.bolt-folder.md)
