blowhorn schedule
blowhorn schedule: bootstrap, delete, get, list, pause, resume, status, tick, trigger-now, upsert, validate, why.
The blowhorn schedule commands. Each one's --help prints the same text.
| Command | What it does |
|---|---|
schedule bootstrap |
Preview or write a validated schedule starter set. |
schedule delete |
Delete a scheduled action by number. |
schedule get |
Return a single scheduled action with all fields. |
schedule list |
List scheduled actions and whether they are currently due. |
schedule pause |
Pause all scheduled processing: every tick keeps running but claims no rows until 'blowhorn schedule resume', and due times carry forward. |
schedule resume |
Resume scheduled processing after 'blowhorn schedule pause'; rows that fell due meanwhile run once, on the next tick. |
schedule status |
Show whether processing is paused, the last tick's heartbeat, the estimated next tick, today's tick counts from the run ledger, and the scheduler LaunchAgent state. |
schedule tick |
Run one scheduler polling pass against due scheduled actions, executing each through the same command routing the CLI uses and writing a per-job log under <log-dir>/scheduler/. |
schedule trigger-now |
Force a specific scheduled action to run immediately. |
schedule upsert |
Create or update a scheduled action from a JSON payload. |
schedule validate |
Validate the schedule's actions against the supported schema. |
schedule why |
Explain why a scheduled row has or has not run on this machine, in the order the scheduler decides it. |
blowhorn schedule bootstrap
Preview or write a validated schedule starter set.
blowhorn schedule bootstrap [OPTIONS]| Flag | Type | Default | Description |
|---|---|---|---|
--replace |
boolean | false |
Replace the current scheduled actions before writing sample ones |
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule bootstrap' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule bootstrap --dry-run
blowhorn schedule bootstrap
blowhorn schedule bootstrap --replaceOutput: json with --json, text otherwise.
blowhorn schedule delete
Delete a scheduled action by number.
blowhorn schedule delete [OPTIONS] row| Argument | Required | Description |
|---|---|---|
row |
yes | Row number to delete |
| Flag | Type | Default | Description |
|---|---|---|---|
--expected-fingerprint |
string | Reject the delete if the current row fingerprint no longer matches | |
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule delete' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule delete 7 --json
blowhorn schedule delete 7 --expected-fingerprint 3f2a1cOutput: json with --json, text otherwise.
blowhorn schedule get
Return a single scheduled action with all fields.
blowhorn schedule get [OPTIONS] row| Argument | Required | Description |
|---|---|---|
row |
yes | Row number to inspect |
| Flag | Type | Default | Description |
|---|---|---|---|
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule get' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule get 7 --json
blowhorn schedule get 7Output: json with --json, text otherwise.
blowhorn schedule list
List scheduled actions and whether they are currently due. With several machines sharing the store the Locked By column names the holder and marks this machine's own claims; a paused action reads paused: yes beside its due state, because due keeps meaning its time has passed.
blowhorn schedule list [OPTIONS]| Flag | Type | Default | Description |
|---|---|---|---|
--due-only |
boolean | false |
Show only rows that are currently due |
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule list' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule list --due-only --profile all
blowhorn schedule list --profile all
blowhorn schedule list --jsonOutput: json with --json, text otherwise.
blowhorn schedule pause
Pause all scheduled processing: every tick keeps running but claims no rows until 'blowhorn schedule resume', and due times carry forward. A job already running finishes first. Pausing has three scopes and a row is claimed only when none of them says paused: without a flag it is this machine only (a local file, never the store), --all is every machine sharing the store, and --row N is one scheduled row on every machine.
blowhorn schedule pause [OPTIONS]| Flag | Type | Default | Description |
|---|---|---|---|
--reason |
string | Short note stored with the pause and shown by 'blowhorn schedule status' | |
--all |
boolean | false |
Pause every machine sharing this store, not just this one: no machine claims a row until 'blowhorn schedule resume --all'. Recorded in the store with who paused it and why, so every machine reports the same reason. Without this flag the pause is this machine only |
--row |
integer | Pause one scheduled row instead of a whole machine: that job is claimed by nobody until 'blowhorn schedule resume --row N', and every other row keeps running everywhere. Distinct from setting the row's Enabled to no, which is an editorial state with no reason and no intent to resume | |
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule pause' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule pause
blowhorn schedule pause --all --reason "LinkedIn challenge on kate"
blowhorn schedule pause --row 7
blowhorn schedule pause --reason "LinkedIn challenge on kate" --jsonOutput: json with --json, text otherwise.
blowhorn schedule resume
Resume scheduled processing after 'blowhorn schedule pause'; rows that fell due meanwhile run once, on the next tick. The same three scopes: without a flag this machine's own pause is lifted, --all lifts the pause every machine sharing the store honours, and --row N lifts one paused action. Lifting one scope leaves the other two as they were.
blowhorn schedule resume [OPTIONS]| Flag | Type | Default | Description |
|---|---|---|---|
--all |
boolean | false |
Lift the pause every machine sharing this store honours, the one 'blowhorn schedule pause --all' set. This machine's own pause and any paused action stay as they are |
--row |
integer | Let one held scheduled row be claimed again, on every machine, the one 'blowhorn schedule pause --row N' held. Every other scope stays as it is | |
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule resume' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule resume
blowhorn schedule resume --all
blowhorn schedule resume --row 7
blowhorn schedule resume --jsonOutput: json with --json, text otherwise.
blowhorn schedule status
Show whether processing is paused, the last tick's heartbeat, the estimated next tick, today's tick counts from the run ledger, and the scheduler LaunchAgent state.
blowhorn schedule status [OPTIONS]| Flag | Type | Default | Description |
|---|---|---|---|
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule status' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule status
blowhorn schedule status --jsonOutput: json with --json, text otherwise.
blowhorn schedule tick
Run one scheduler polling pass against due scheduled actions, executing each through the same command routing the CLI uses and writing a per-job log under <log-dir>/scheduler/. While 'blowhorn schedule pause' is in effect the pass claims nothing unless --ignore-pause is passed; a real pass also records its heartbeat in <log-dir>/scheduler/last-tick.json and appends one tick record to the run ledger, <log-dir>/runs/<YYYY-MM>.jsonl. Browser visibility comes from each job: its own headless=/headed= params, then the environment, then Settings.
blowhorn schedule tick [OPTIONS]| Flag | Type | Default | Description |
|---|---|---|---|
--limit |
integer | 0 |
Maximum number of due rows to process; 0 means no limit |
--ignore-pause |
boolean | false |
Run even while 'blowhorn schedule pause' is in effect; without it a paused scheduler claims nothing |
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Pace handed to every action 'blowhorn schedule tick' runs in-process this pass -- the random delays between that action's browser or API steps: a preset name (fast/normal/slow) or a numeric multiplier (e.g. 0.5, 2.0). Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule tick --profile all --dry-run
blowhorn schedule tick --profile all --limit 5
blowhorn schedule tick --profile all --limit 0
blowhorn schedule tick --profile all --ignore-pauseOutput: json with --json, text otherwise.
blowhorn schedule trigger-now
Force a specific scheduled action to run immediately. While 'blowhorn schedule pause' is in effect the row is not run and the command exits 1, unless --ignore-pause is passed. Browser visibility comes from the job: its own headless=/headed= params, then the environment, then Settings.
blowhorn schedule trigger-now [OPTIONS] row| Argument | Required | Description |
|---|---|---|
row |
yes | Row number to execute |
| Flag | Type | Default | Description |
|---|---|---|---|
--ignore-pause |
boolean | false |
Run even while 'blowhorn schedule pause' is in effect; without it a paused scheduler claims nothing |
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Pace handed to every action 'blowhorn schedule trigger-now' runs in-process this pass -- the random delays between that action's browser or API steps: a preset name (fast/normal/slow) or a numeric multiplier (e.g. 0.5, 2.0). Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule trigger-now 7 --dry-run
blowhorn schedule trigger-now 7
blowhorn schedule trigger-now 7 --ignore-pauseOutput: json with --json, text otherwise.
blowhorn schedule upsert
Create or update a scheduled action from a JSON payload. Giving a completed or failed row a new Next Run At, or a Run At that changes, schedules it again in place with a fresh retry budget (Status scheduled, Retry Count 0; its last run and last error are kept); raising Max Retries alone does not.
blowhorn schedule upsert [OPTIONS]| Flag | Type | Default | Description |
|---|---|---|---|
--payload |
string | JSON object representing scheduled action fields | |
--row |
integer | Row number to update; omit to create a new row | |
--expected-fingerprint |
string | Reject the write if the current row fingerprint no longer matches | |
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule upsert' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule upsert --payload '{"Command":"report","Profile":"all","Run At":"2026-03-12 08:00:00"}' --json
blowhorn schedule upsert --row 7 --payload '{"Run At":"2026-03-13 08:00:00"}' --json
blowhorn schedule upsert --row 4 --payload '{"Next Run At":"2026-10-20 09:00:00"}' --json
blowhorn schedule upsert --row 7 --payload '{"Enabled":"FALSE"}' --expected-fingerprint 3f2a1c --jsonOutput: json with --json, text otherwise.
blowhorn schedule validate
Validate the schedule's actions against the supported schema.
blowhorn schedule validate [OPTIONS]| Flag | Type | Default | Description |
|---|---|---|---|
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule validate' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule validate --profile all
blowhorn schedule validate --profile all --jsonOutput: json with --json, text otherwise.
blowhorn schedule why
Explain why a scheduled row has or has not run on this machine, in the order the scheduler decides it: whether the row is enabled and valid, whether anything is pausing it (the row itself, this machine, or every machine), whether it is due, whether another machine holds the claim and when that lease expires, whether this machine can reach the store and when it last ticked, and what the run history says happened the last time it ran. Reads only -- it claims nothing, runs nothing and changes nothing, so it is safe against a row that is mid-flight.
blowhorn schedule why [OPTIONS] row| Argument | Required | Description |
|---|---|---|
row |
yes | The scheduled action's number to explain (the same number 'blowhorn schedule list' prints) |
| Flag | Type | Default | Description |
|---|---|---|---|
--json |
boolean | false |
Emit machine-readable JSON output |
--platform |
string | all |
Platform filter for 'blowhorn schedule': it selects which scheduled rows this command reads or acts on, and is not a platform blowhorn posts to directly. One of: bluesky, github, hn, linkedin, reddit, slack, x, all ('all' applies no filter, so every scheduled row is included) |
--pace |
string | Accepted by 'blowhorn schedule why' because --pace is a global flag, but this command does no paced work -- it opens no browser and sleeps between nothing -- so the value changes nothing about how it runs and appears only in the Pace column of the -v summary. Resolved as CLI flag, then BLOWHORN_PACE, then defaults.pace in .blowhorn.yaml (normal when none is set); an unrecognized value is rejected before anything runs |
Also takes the shared flags: --config, --log-dir, --profile, --exclude, --headless, --chrome-launch, --headed, --dry-run, --verbose.
Examples:
blowhorn schedule why 7
blowhorn schedule why 7 --jsonOutput: json with --json, text otherwise.