October 2026 · For current behavior, see Typed Payload Contracts.
What Shipped
Wiring your service to a Brew trigger used to mean keeping the payload shape in sync by hand. Your code sends one shape, and your email reads another. A renamed field surfaced at fire time, as a failed run or an email that fell back to its default. Now every trigger has a typed contract. Generate it as TypeScript and check it in CI. A payload change then shows up in code review, not in production.How It Works
1
Generate types
brew-cli types --out src/brew-contracts.ts writes one type per trigger in
the brand. Pass a type to the SDK’s fire<T>(), and a missing field or a
wrong type becomes a compile error.2
Catch drift in CI
brew-cli types --check exits 1 when the brand’s contracts no longer
match the committed file. Regenerate, review the diff, and merge.3
Dry-run a payload
POST /v1/automations/triggers/{triggerEventId}/contract/validate runs a
payload through the same validator a real fire uses. Nothing fires or
sends.Store and Enforce a Contract
Brew derives a contract from each trigger’s schema, so types work with no setup. To go further, store one:- Draft it from a real payload.
POST /v1/payload-contracts/infertypes an example for you. Nothing is saved until youPUTit to the trigger. - Choose how strict a fire is. Enforcement starts
off.prunedrops keys the contract doesn’t declare, andstrictrejects a payload that carries them. - Mark one-time values secret. A reset token or sign-in link marked
secretrenders in the email and is never stored on the contact or in logs.
Built for Agents
A trigger read with?include=skill returns a SKILL.md brief that a coding
agent can follow to wire your service. It carries the endpoint, auth, the typed
contract, and a test loop. In the app, the trigger’s contract panel offers the same file
under Copy as → Download SKILL.md.
Over MCP, get_trigger_contract, infer_payload_contract,
set_trigger_contract, and check_trigger cover the same steps.