The postboi package carries a CLI: bunx postboi <command> (or npx). Setup and the
dev tools work with any provider; the account commands need the Postboi provider’s POSTBOI_TOKEN, which init writes. Every account command takes --json for the API’s
response as one document, and a failure carries the API’s code, which is what a script or
an agent should branch on.
Setup and tools
| Command | What it does |
|---|---|
bunx postboi init | Set up the Postboi provider or a provider of your own: Installs postboi, adds the postboi() Vite plugin, writes postboi.config and runs sync · --agent: zero prompts, zero sign-in. Provisions a claimable sandbox account (made for AI coding agents and CI) · --sms · --whatsapp · --push · --chat: set up that channel instead · --github: open dashboard-approved GitHub workload trust; --workload <id> writes a keyless workflow (--workflow <name.yml>, --run <command>) |
bunx postboi sync | Pull synced team credentials and refresh the generated from/template types: Bakes the captcha key for <Captcha />; warns when node_modules is behind the lockfile |
bunx postboi env | The synced credentials: push · pull [--force] · remove <KEY> |
bunx postboi vapid | Mint a VAPID key pair for Web Push, printed to stdout. —export prints managed push’s pair |
bunx postboi doctor | Is this project wired? Install, token, provider, from address, webhooks, captcha key, SMS, skill: --json · exit 1 on a failure · --sms-text "…" previews a text's encoding and segments · --sms-live --to <n> --confirm-to <n> --confirm-from <sender> sends one real text |
bunx postboi skill | Install the agent skill, so AI coding agents know the library |
bunx postboi dev | Local inbox for mail sent in development: --port <n> --demo --no-sound --no-intro · (Vite projects already serve it at /__postboi) |
bunx postboi inspect | Lint an email’s HTML: client compatibility, clipping, dead links: <file.html> · --links --subject <s> --json (exit 1 on warnings) |
The account
Postboi provider. Full reference: https://api.postboi.app
| Command | What it does |
|---|---|
bunx postboi whoami | The account behind your token |
bunx postboi send | One email, now: --to <emails> --subject <s> --text <t>, --html <h> or --file <body> [--at <ISO>] · --file uploads the local images and fonts the HTML points at, as assets does; --no-assets sends it as it is |
bunx postboi assets | Host the images and fonts built email HTML points at, for good: <file.html…> uploads the local files they point at (src, srcset, url(), VML) and rewrites each file in place to the hosted URLs · - reads stdin and writes the HTML to stdout. Shared files go up once per run; URLs are on mail-view.<your domain> when it's on |
bunx postboi send-address | Default sending address: [name@yourdomain.com] |
bunx postboi lists | Lists: add <name> · send <list> --subject <s> --text, --html or --file <body> · delete <ref> · send --file uploads the local images and fonts the HTML points at, as assets does; --no-assets sends it as it is |
bunx postboi recipients | A list’s recipients: <list> add <email>… · <list> remove <email> |
bunx postboi contacts | The audience: add <email> [--name --phone --data] · <email> · remove <email> |
bunx postboi domains | Sending domains: add <domain> · check <ref> · inbound <domain> [--off] · delete <ref> |
bunx postboi migrate resend | Move a Resend account here: domains, audiences as lists, webhooks: [--key <resend key>] [--only domains,lists,webhooks] [--dry-run] [--json] · Reads RESEND_API_KEY when --key is absent. Safe to run twice: what is here already is skipped |
bunx postboi webhooks | Webhooks: add <url> · rotate <id> · deliveries <id> · delete <id> |
bunx postboi members | Members: invite <email> · remove <ref> · revoke <ref> |
bunx postboi messages | Recent messages: [status] · <id> (status, opens, fields) · cancel <id> |
bunx postboi exports | Exports: download [--form <form>] [--xlsx] [--out <file>] · add <name> --to <emails> --weekly · run · pause · resume · delete <id> |
bunx postboi suppressions | Suppressed addresses: add <email or +phone> · remove <email or +phone> |
bunx postboi forms | The forms submissions are filed under: (named in your code) |
bunx postboi notifications | A list’s digests: <list> · <list> add --to <emails> --weekly or --on-signup · <list> delete <id> |
bunx postboi testing | Email tests: a report and real-client screenshots: run <file.html or -> pastes it, waits for every screenshot and saves them to screenshots/<series>/<group>/<client>.png · run: --series (default: the file name) --clients a,b or --set <name> or --all (batched) --fresh --out <dir> --no-wait --share --yes; exits 1 on an error report or a failed capture · run and add --html upload the local images and fonts the HTML points at (src, srcset, url(), VML) and point it at the copies; --no-assets sends it as it is · download <id> [--out dir]: wait out an existing run and save its screenshots · add [--label] [--series] [--clients or --set] [--html <file>] · <id> (the report) · clients · delete <id> · sets · sets save <name> --clients a,b · sets delete <name> · share <id> [--revoke] |
bunx postboi views | Web versions of emails, for a View in browser link whoever sends them: publish <file.html> [--slug <s>] [--context <file.json or .js>] [--provider onesignal, braze, iterable, customerio, klaviyo, mailchimp, sendgrid or none] · publish: --public <var[:integer, date or enum]>,… or --public all makes reader variables URL params; the rest come through the sender's data feed · publish: prints the link in the sender's merge syntax and the feed setup; --write puts the link in the file and data-web-hide on unsubscribe links (--yes skips asking) · publish: --reader <template path> puts the reader's id on the link as u, for view.viewed webhooks (opt-in: anyone can edit it; off turns it off) · publish: uploads the local images and fonts the HTML points at (kept, unlike test uploads) and publishes it pointing at the copies (the file keeps its paths); --no-assets leaves the local paths as they are · stats <slug> [--days 30]: views and visitors per day, by public params, and how many were identified · open <slug> [--data <json>] [--param key=value] · delete <slug> · keys [rotate] · feed-key |
A bare noun lists; list says the same. Add —json to any of them for the API’s response as JSON (errors carry the API’s code).
Temp inboxes
tempboi.email, no account or POSTBOI_TOKEN needed
| Command | What it does |
|---|---|
bunx postboi inbox | Make a throwaway inbox and print its address: new [--name <n>] [--ttl 2h] [--json] [--env] · --env prints export POSTBOI_INBOX=… POSTBOI_INBOX_TOKEN=… for eval |
bunx postboi inbox watch | Print mail as it arrives, one line each: [address] --all --json (NDJSON) --tag <t> --from <s> --subject <s> · --forward <url>: POST each as an email.received webhook, signed with POSTBOI_WEBHOOK_SECRET when set · --exec <cmd>: run per mail with SUBJECT FROM TO CODE LINK ID set and the mail's JSON on stdin |
bunx postboi inbox wait | Wait for one mail, then exit: [address] --from <s> --subject <s> --tag <t> (/regex/ works) --timeout <sec> --new · --code or --link prints only that (exit 3 if absent) · --json · exit 2 on timeout |
bunx postboi inbox read | One mail in full: [id or latest] --html --raw --headers --json |
bunx postboi inbox open | The inbox’s web page, in your browser |
bunx postboi inbox ls | Inboxes made on this machine: rm [address] · extend <ttl> [address] |
The inbox made or used last is the default; POSTBOI_INBOX_TOKEN overrides it (the token alone finds its inbox), POSTBOI_INBOX_URL moves the host.
Agent mailboxes
agentboi.email; no POSTBOI_TOKEN needed to make one
| Command | What it does |
|---|---|
bunx postboi mailbox new | Make an address your agent keeps, and print it: [--address <name>] [--name <label>] [--domain <yours>] [--ttl 1h] [--json] [--env] · With POSTBOI_TOKEN it is your team's; without, it sends once you open its claim link · --env prints export POSTBOI_MAILBOX_KEY=… for eval |
bunx postboi mailbox watch | Print mail as it arrives, one line each, with who is talking: [address] --all --json (NDJSON) --trust <owner, thread, stranger or suspect> --tag --from --subject · --exec <cmd>: run per mail with ID THREAD TRUST FROM SUBJECT REPLY_TEXT CODE LINK set |
bunx postboi mailbox wait | Wait for one mail, then exit: [address] --from --subject --tag --trust (/regex/ works) --timeout <sec> --new · --code or --link prints only that (exit 3 if absent) · --json · exit 2 on timeout |
bunx postboi mailbox read | One mail in full: what they wrote, minus the quoted thread: [id or latest] [address] --html --raw --json |
bunx postboi mailbox reply | Answer a mail in its thread: <id> [address] --text "…" (or --html) --cc a,b --bcc c --subject "…" --attach a.pdf,b.png · Under review it is saved as a draft for a person to send: the draft's id is printed, and stderr says so |
bunx postboi mailbox send | A new message from the mailbox: [address] --to a@b.com,c@d.com --subject "…" --text "…" --in-reply-to <id> --attach <files> |
bunx postboi mailbox forward | Send a mail on to somebody else, with a note above it: <id> [address] --to a@b.com --text "…" --no-attachments |
bunx postboi mailbox threads | Its conversations, newest activity first: [address] --folder <inbox, archive, spam, trash, sent or all> --label <name> --unread or --read --q <search> --limit <n> · archive <thread> · trash <thread> · move <thread> <folder> · mark <thread> [--unread] |
bunx postboi mailbox label | Label a thread; a name that isn’t a label yet becomes one: <thread> <name…> [--remove] [--mailbox <address>] |
bunx postboi mailbox labels | Its labels, with how many threads carry each: [address] · add <name> [--colour <grey, amber, red, green or blue>] · rm <name> |
bunx postboi mailbox drafts | Drafts waiting for a person, newest first: [address] --status <draft, sent or all> · draft new --to --subject --text --in-reply-to <id> --attach · draft <id> · draft edit <id> --text "…" · draft send <id> · draft rm <id> |
bunx postboi mailbox review | Who has to look before it sends: none, new (new conversations) or all: [none, new or all] [address]: changing it needs your team's POSTBOI_TOKEN; with no value it prints the current one |
bunx postboi mailbox ls | Mailboxes on this machine: key [address] [--ttl 1h]: a new key, the old one stops; omission keeps expiry · rm [address] · disable [address] · enable [address]: team key required; enabling needs a fresh key |
The mailbox made or used last is the default, then the team’s with POSTBOI_TOKEN; POSTBOI_MAILBOX_KEY overrides both (the key alone finds its mailbox). —mailbox
names one on any command; POSTBOI_MAILBOX_URL moves the host.MCP
for agents: Claude Code, Cursor, Codex and any MCP client
| Command | What it does |
|---|---|
bunx postboi mcp | Run an MCP server on stdio: mailboxes, temp inboxes and sending, as tools: Reads the project's .env: POSTBOI_TOKEN opens the team's mailboxes and sends with email_send · Without one, a mailbox it makes is kept on this machine for the next session · claude mcp add postboi -- npx postboi mcp |
For agents
bunx postboi init --agent provisions a claimable sandbox account with no prompts and no
sign-in, bunx postboi skill installs the agent skill that teaches the library, and bunx postboi doctor says whether a project is wired. This page is also plain Markdown at /raw/cli.