Scheduled runs
BrainyShorts keeps the schedule, targets, and history. A runner on your own machine does the research and generation when a run is due.
An automation is a skill that runs on a schedule. BrainyShorts stores what should happen (skill version, cron, targets, publish mode). A runner you control decides when to wake your agent and does the actual work. BrainyShorts never calls a model and never hands your agent a social platform token.
How a run works
Create the automation
An agent connected over MCP loads a skill with brainy_get_skill, registers the machine with brainy_register_executor, and calls brainy_create_automation. BrainyShorts validates it, stores revision 1, and returns an install manifest.
The runner syncs
brainy-shorts-runner tick calls GET /api/agent/automations/sync, installs new revisions, removes paused or deleted ones, and acknowledges each applied revision with POST /api/agent/automations/{id}/ack. Idle ticks never invoke a model.
A run starts
When the cron is due, the runner calls POST /api/agent/automations/{id}/start with the idempotency key <automation_id>:<revision>:<scheduled_for>. BrainyShorts checks the automation is still enabled and current, then returns a ba_run_... token that is valid for 6 hours and bound to that single run.
Your agent does the work
The runner launches your agent with BRAINY_RUN_TOKEN in its environment. The agent posts progress to /api/agent/runs/{id}/events and uploads media through /api/agent/runs/{id}/media/uploads.
The run completes
The agent calls POST /api/agent/runs/{id}/complete-local, or /fail. BrainyShorts then creates a draft, or publishes when the automation’s publication mode is auto.
Automation settings
| Setting | Values |
|---|---|
| Publication mode | draft (default) or auto |
| Schedule | cron expression plus an IANA timezone |
| Missed runs | skip, run_once, or catch_up |
| Skill | id and pinned version, see Skills |
Turning on auto is a separate decision from creating the automation. Pausing or disconnecting an account takes effect immediately, because every run start and completion is checked on the server.
Runner
The reference runner brainy-shorts-runner currently ships inside the BrainyShorts repository rather than on npm. It needs Node 20 or newer and uses the codex adapter.
cd runner && npm install && npm link
export BRAINY_API_KEY="ba_sk_..."
brainy-shorts-runner install ./automation.json
brainy-shorts-runner tick <executor-id> # run this from cron or launchd every minute
| Command | What it does |
|---|---|
install <file or -> |
Install a manifest and acknowledge its revision |
list |
Installed manifests |
remove <automation-id> |
Uninstall one |
sync <executor-id> |
Pull desired revisions |
run |
Start due runs, using no network when nothing is due |
tick <executor-id> |
sync followed by run, which is the normal scheduler command |
Any process that speaks the HTTP endpoints below can act as a runner, so you can write your own in any language.
Runner endpoints
All of these live under https://www.brainyshorts.com/api/agent. The first three take an API key; the rest take the run token.
| Method | Path | Auth |
|---|---|---|
POST |
/executors |
API key |
GET |
/automations/sync |
API key |
POST |
/automations/{id}/ack, /automations/{id}/start |
API key |
GET |
/runs/{id} |
run token |
POST |
/runs/{id}/events |
run token |
POST, PATCH |
/runs/{id}/media/uploads |
run token |
POST |
/runs/{id}/direct-upload, GET /runs/{id}/direct-upload/status |
run token |
POST |
/runs/{id}/complete-local, /runs/{id}/fail |
run token |
direct-upload returns a provider upload session so TikTok and YouTube video bytes go straight from your machine to the platform, up to 64 MiB. A YouTube handoff also needs the parent runner’s API key in x-brainy-runner-key, so only the trusted runner process, not the spawned agent, can stage a YouTube upload. Instagram, LinkedIn, and X use managed media instead.
Legacy claim queue
Automations created before local_push use a pull queue. A runner claims work with an API key, then renews, completes, skips, or fails it with the returned claim_token:
POST /api/agent/runs/claim → /runs/{id}/renew → /runs/{id}/complete | /skip | /fail
The queue still works for existing Instagram automations. Create new automations over MCP.
