Plan format (TOML)

Plans are TOML documents. The structured editor (Targets / Constraints / Focus / etc.) generates them; you can also edit them directly.

Top-level


[meta]
name = "M42 LRGB"
notes = "test imaging plan"
author = "Pete"          # optional
created = "2026-06-28"   # optional, ISO time
version = 1

[defaults]               # optional: default args shared by steps
binning = 1

[variables]              # optional: initial variable values
target_name = "M42"

[[steps]]
kind = "..."

A plan is a list of [[steps]]. Each step has a kind and per-kind args. The optional [defaults] and [variables] tables give you plan-wide default values and starting variables you can reference from steps.

Step kinds

expose


[[steps]]
kind = "expose"
count = 20
exposure_s = 300
binning = 1              # optional; omit to use [camera] default_binning
gain = 100              # optional
offset = 30            # optional
light = true          # optional; false for calibration frames
object_name = "M42"   # optional; defaults to the current target name
filter_name = "Ha"    # optional; recorded in the file header

dither

A dither step nudges the mount through PHD2 so hot pixels and walking noise average out. It only fires when guiding and dithering are enabled for the plan (Guiding tab) and PHD2 control is on — otherwise it's a harmless no-op that just records the request. The nudge size defaults to the plan's dither pixels; override it with amount_px. The settle gate (settle pixels / time / timeout) comes from the plan's guiding settings.

You usually don't need explicit dither steps: when guiding + dithering are on, Starship automatically dithers every N frames (the "dither every N exposures" setting) between subs, no matter how they're grouped.

focus

A focus step moves the focuser to a set position:


[[steps]]
kind = "focus"
position = 2500
relative = false        # optional; true moves by an offset instead

Automatic refocus (running a real autofocus during the run) is driven by the plan-level focus policy, not by the focus step — see below. A focus step with autofocus = true is reserved and not yet wired.

wait_until

wait_until blocks until the first matching condition is met (checked in this order):

Add timeout_min to give up after that many minutes (the step then fails, so its error policy decides what happens next; 0 means fail immediately). Omit it to wait indefinitely.

Plan-level policy

Policy from the structured editor's tabs is encoded in a single hidden notes step at the top:


[[steps]]
kind = "notes"
label = "plan policy"
_policy = { constraints = { altitude_min_deg = 30.0, ... }, focus = { ... }, cooling = { ... }, meridian = { ... }, guiding = { ... }, on_end = { ... }, phases = { ... } }

The executor reads this on plan start and applies the policies as the run progresses. The blocks cover:

You can edit any of this directly in the TOML tab if you want fine control.

Per-step error handling


[[steps]]
kind = "expose"
on_error = "retry"        # 'abort' | 'skip' | 'retry'
retry_count = 2

abort stops the sequence, skip logs and moves on, and retry retries up to retry_count times before falling back to skip. Every step can also carry an optional label that shows up in the run journal.

Variable substitution

Loop bodies can reference $target_name, $target_ra_h, $target_dec_deg (bound by loop_targets), the iter counter inside a repeat, and any variable set with a set step or in the [variables] table. Whole-string references preserve type ("$target_ra_h" resolves to a number). Partial interpolation works too ("Imaging $target_name now"). Note that repeat.count itself must be a literal number, not a variable.

Why TOML

Human-readable, line-diffable, easy to share via email or git, no security risk on parse. All Starship config is TOML, so plans match.

Astroworx Starship v22.2.10 · this page is the in-app help of that buildDownload · HTTP API