One URL, one header, one YAML step
The parts were already on the shelf. AgentMail is an API-first inbox built for agents: you mint an inbox over the API, it takes delivery, and it fires a webhook at a URL you choose the moment mail arrives. Buzz, the open source workspace published by Block (Hachiflow is independent and not affiliated with Block), ships a workflow engine on the relay itself. Every workspace on hachiflow.chat has it built in, so webhook-triggered workflows just work on day 1, with no server of your own to run.
A workflow with a webhook trigger gets an endpoint like POST https://yourteam.hachiflow.chat/hooks/9f4c21e7-6b3d-4a8e-b02f-c75d10a94e63, authenticated with an X-Webhook-Secret header. Point AgentMail's webhook at that URL, put the secret in the header, and inbound email lands in your channel.
That's the whole integration: one URL, one header, one YAML step. The screenshot below is the entire Buzz side of it, and the terminal after that is the entire contract, with deliberately fake example values.
Obie wartości są celowo fałszywymi przykładami: prawdziwy UUID hooka i sekret powstają przy tworzeniu workflow, a sekret trzyma się wyłącznie w konfiguracji webhooka AgentMail.
Attempt 1: the wall of JSON
Our first workflow did the obvious thing: it templated the payload straight into the channel with {{trigger.message}}. What came out was a wall of raw JSON. Headers, SPF results, attachment metadata, the whole envelope as one paragraph. It's preserved in the screenshot further down, sitting right above its replacement.
The limitation is specific, and we read the Rust to confirm it. Buzz workflow templates today lift only the top-level keys of the webhook body. A nested object renders as one stringified blob: there is no {{trigger.message.from}}, and the only template filters are truncate and npub. Rendering a nested webhook payload nicely inside a workflow message is not currently possible.
That's not a complaint. It's a young engine and the template surface will grow. But today the honest advice is: don't plan to format your webhook payload in the workflow, plan around it.
Don't render in the workflow. Don't render at all.
The way out was staring at us from every other message in the channel. Agent messages in Buzz look great, because the client renders message content as GitHub-flavored markdown. The workflow couldn't format the mail, but the teammate it was delivering to formats everything he says. So we flipped the architecture and stopped rendering in the workflow entirely.
The workflow message is now a one-line doorbell that @mentions the agent. Gary V holds the AgentMail tools himself, their hosted MCP server, scoped to just this one inbox. When the doorbell rings, he fetches the unread mail, posts a readable markdown card plus his draft reply in the channel, sends the reply threaded on the original message through the AgentMail API, and labels the message handled so nothing gets worked twice.
The agent is the rendering layer. The workflow is a wake-up call. And approval never moved: Gary drafts in the channel, and a founder says go before anything leaves the building.
The mention that wakes no one
Gotcha 1 cost us 3 test rounds. Mentions in workflow messages are resolved server-side: the relay matches the @Name in your step text against the channel's members by display name. If 2 members share a display name, the relay deliberately wakes no one. No error, no partial match, no log you can see. Silence.
We had a stale duplicate: an earlier, dead "Gary V" was still a member of the channel next to the live one, so every doorbell rang for nobody. As an anti-misroute rule this is reasonable, you don't want a workflow guessing which of 2 same-named members to wake. As a debugging experience it's brutal, because nothing anywhere tells you it happened. We kicked the stale member and the doorbell rang.
The byline is cosmetic
Gotcha 2 is subtler. A workflow message looks like it comes from you. It doesn't. The client renders the attribution; cryptographically, the message is signed by the relay's own key.
Gary's respond-to gate was set to owner only, and the gate checks the signature, not the byline. So he watched the doorbell arrive, saw it wasn't signed by his owner, and correctly ignored it. The gate is right, the byline is cosmetic, and the fix is to allowlist the relay's key for the agent, so relay-signed workflow messages count as a wake.
We found this by reading the buzz-acp source, and upstream has wrestled with the same issue: a fix landed and was reverted. So if your agent gets tagged and never wakes, and there's exactly 1 of him in the channel, this is why.
One more for the road
A small one from the workflow YAML editor. A text value that starts with @ must be quoted, because a bare @ can't start a YAML scalar. And paste carefully: we once managed to append an entire second YAML document into the message text field, and the editor took it without a blink. The form and YAML views are 2 doors to the same step; the form one bites less.
Fixing the tools you're holding
Every test round was a real email from our own domain, sent with higgs, our CLI for Proton Mail that drives Proton Mail Bridge over IMAP and SMTP. No mocks: each test crossed the real internet, landed in the real inbox, and rang the real doorbell, which is exactly how we caught gotchas a fixture never would have surfaced.
Dogfooding cut both ways. Mid-debug we found that higgs send couldn't talk to Bridge out of the box, so we fixed it and shipped higgs v1.3.0 the same night. That's what the real work of wiring agents together looks like: half the time you're fixing the tools you're holding.
Alpha-grade, and it ships
Everything above runs today on any Hachiflow workspace: $50 a month flat, unlimited people and unlimited agents, your own LLM keys, a dedicated server. Nothing here needed custom infrastructure. AgentMail is a product you can sign up for, the workflow engine ships in every workspace, and the agent is a member of your team like anyone else.
Buzz is young and this is alpha-grade wiring with rough edges, which is exactly why we publish the gotchas instead of a highlight reel. If you want an inbox with a teammate behind it, start at hachiflow.com.