A playbook is a short, readable YAML file that says “when this happens, do these steps.” You don’t write code — you describe the outcome, and Binions coordinates its background services (the daemons) to make it happen. This page walks you through writing and running your very first playbook in about five minutes.
Before you start. You’ll need Binions already installed on your host — see the Quick start. This guide assumes you’re comfortable editing a file over SSH.
A tiny invoice catcher. When an email lands in a watched mailbox, Binions pulls a few key fields out of it with AI and saves them to a database table — no copy-paste, no manual data entry. That’s two steps and a trigger: small enough to read at a glance, real enough to be useful.
Every Binions playbook is made of the same few pieces. There’s no language to learn and no logic to script — that work lives inside the daemons.
mode: field (either saga or async, default saga) controls how the engine runs steps. In saga mode each run: step waits for its result before the next one starts; in async mode run: steps fire immediately without waiting, letting you fan out several actions at once.run:). The most common step: calls one operation on one daemon, such as ai.extract or database.write. In saga mode these run one after another; in async mode they fire concurrently.parallel:). When two or more steps are truly independent, wrap them in a parallel: block to run them at the same time regardless of mode.loop:). Repeat a step (or a short sequence of steps) a bounded number of times — for example, to process each item in a fixed-size batch. A hard cap prevents runaway iteration.wait_for:). Used in async mode to pause and wait for the response fact from a specific earlier fire-and-forget step, identified by its correlation id. This is how you collect results after fanning out.Steps pass data to each other with simple placeholders: ${trigger.…} reads a field from the triggering event, ${prev.…} carries the previous step’s result forward (in saga mode), and ${steps.<id>.…} reuses the result of any named earlier step. See the Playbook anatomy reference for the complete grammar.
Create a file called invoice-catcher.yaml and paste this in:
name: invoice-catcher
description: "When mail arrives, extract invoice fields with AI and save them."
trigger:
event: Fact.Mail.Received
filter:
via.eq: accounts-inbox # the mailbox alias to watch
steps:
- id: extract
run: ai.extract
with:
text: ${trigger.envelope.body_text}
fields:
- { name: supplier_name, hint: "company that issued the invoice" }
- { name: invoice_number, hint: "invoice or document number" }
- { name: amount_gross, hint: "total amount including taxes" }
- id: save
run: database.write
with:
table: invoices
row:
from_email: ${trigger.from}
subject: ${trigger.subject}
ai_extract: ${steps.extract.result}
Reading it top to bottom:
trigger — fire whenever a new email is received (Fact.Mail.Received) in the mailbox registered under the alias accounts-inbox.extract — hand the email body to the AI daemon and ask it for three named fields. You describe what to pull out; the daemon does the rest.save — write a row into the invoices table. ${trigger.from} and ${trigger.subject} come straight from the email; ${steps.extract.result} reuses the AI output from the previous step.Names, not secrets. A playbook refers to the mailbox and the table by name only — never passwords or connection strings. Those are set up once in a separate provisioning playbook, so this file is safe to read, review, and commit to git.
Playbooks live on your host under /opt/binions/playbook-service/playbooks/. Drop the file into the business/ folder there:
sudo cp invoice-catcher.yaml \
/opt/binions/playbook-service/playbooks/business/
That’s the whole deployment step. Binions watches the playbooks directory and picks up new or changed files on its own — within a couple of seconds, with nothing to restart and nothing to recompile. A file in business/ loads and then waits for its trigger; a file in provisioning/ runs the moment it loads.
Your playbook is now live and listening. To confirm it ran, send a test email to the watched mailbox and watch the event log. Every step is recorded, so you’ll see the run start and finish:
# Live stream of platform events
tail -f /var/log/binions/events.jsonl | jq
# Or check the playbook service directly
journalctl -u binions-playbook.service --since "5 minutes ago" --no-pager
A successful run shows a Fact.Playbook.Started followed by a Fact.Playbook.Completed, with a new row waiting in your invoices table. A real end-to-end run like this — mail in, AI extract, database write — completes in well under a second for the platform steps; any additional time reflects the AI provider’s own response time.
Playbooks are just files. Because each one is a plain YAML file, you can keep them in git, review changes like any other code, and roll them out with zero downtime — drop the file in and it goes live on its own, no restart required.