Skip to main content
Every automation starts with a trigger. This page is the reference for each kind of trigger, what a fire saves on the contact, and how Brew checks a payload. For the nodes that follow the trigger, see Automations. To build a flow on a trigger, follow Build an Automation.

Trigger Events

The trigger picker offers four kinds of trigger:
  • Custom HTTP triggers. Events you define and fire from your backend.
  • Built-in events. Discovered from connected sources such as Stripe billing events.
  • Unsubscribe events. Brew starts these itself when a contact unsubscribes.
  • Manual audiences. A saved audience, run through the flow on demand.
Common trigger moments include new user signup, order placed, trial ending, payment failed, cart abandoned, and subscription canceled. Manage the events on the Triggers page: open Automations and click Triggers.

Changing the Trigger

Click the trigger node to open its config panel. Use Change trigger to select another audience or event without rebuilding the rest of the flow.

Custom Events

A custom event is one you define and fire from your own backend. It has a name and a payload schema, and Brew checks every fire against it before starting any automation. A missing required field or a wrong type fails the fire. Undeclared keys depend on the enforcement mode of the trigger’s stored contract:
  • Off, the default, accepts them and reports a warning.
  • Prune drops them before the run.
  • Strict refuses the fire.
A field with a fallback value never fails a fire for being missing. Every recipient gets the fallback. See Typed Payload Contracts. Names describe the action, such as user_signup, order_placed, or subscription_renewed. Schemas list the fields the event sends, each typed as string, int, boolean, object, or array, with required fields marked. A stored contract adds float, date, and enum. A flat payload, like the one in Build an Automation, keeps merge tags short. A field can also be an object. Declare the nesting and each leaf is addressable by its dotted path, so this schema gives you {{ user.email }} and {{ order.id }}:
Either shape works. Undeclared keys never reach the template, and an automation whose email uses a trigger field the trigger doesn’t declare can’t publish. What a fire saves on the contact. Each fire also creates or updates the contact in its email field:
  • Top-level fields are saved. firstName, lastName, and subscribed fill the contact’s own fields. Other declared top-level fields become custom properties.
  • Objects and lists aren’t saved. A field like order stays available to the email as {{ order.id }}, but it’s not stored on the contact.
  • Fallbacks aren’t saved. A fallback value fills the email only. A subscribed fallback only sets a new contact’s subscription.
  • A value of the wrong type is skipped. Sending "abc" for a number field leaves that field unchanged. The rest of the contact is saved, the automation still runs, and the response carries a FIELD_TYPE_MISMATCH warning.
Create custom events on the Triggers page with New custom trigger, and fire them from your backend. Build an Automation walks through creating, testing, and firing one, with advice on naming and schemas. The API Reference has the contract.

What Happens When a Payload Fails Validation

  • Response. A missing required field or a wrong type returns 400 INVALID_PAYLOAD, and no automation starts.
  • Field errors. details.errors[] names every field that failed, each with a field and a code: missing_required, invalid_type, unexpected_key, invalid_email, or payload_not_object.
  • Retries. The same body fails the same way on retry. Fix the payload against the trigger’s payloadSchema, then send the event again.
Errors owns the envelope and the full code catalog.

Connected-Source Events

Connecting a provider provisions every event Brew supports for it. Most connections mint a webhook URL scoped to your brand, which you paste into the provider’s dashboard. Stripe registers its own. Brew signature-verifies every delivery and rejects tampered or replayed events before anything runs. For every verified event, Brew starts each Live automation whose trigger matches and upserts the contact into your audience with provider-namespaced custom fields (stripeSubscriptionStatus, clerkUserId, and so on) you can use in filters and merge tags. The integration’s Manage tab shows the catalogue and a Recent events stream. Until the provider sends an event at least once, Brew can’t tell whether its webhook is set up. You can still publish an automation on it, with a TRIGGER_EVENT_NOT_RECEIVED warning, and it runs once the event arrives. To check, check_trigger over MCP or GET /v1/automations/triggers/{triggerEventId}/readiness returns delivery: received once Brew has seen the event, or never_received with the setup step to check. An event fires emails only when a Live automation is wired to it. Unpublish the automation to stop new people from entering; anyone already in the flow still finishes. Pause it to hold every send, or disconnect the integration to stop every event. See the Integrations overview for the full list. For the flows a store usually runs on these events, see Lifecycle Emails for E-Commerce. Brew only listens to connected sources. It does not charge customers, modify subscriptions, refund payments, mutate auth records, or change Shopify orders.

Unsubscribe Events

An automation can start when a contact unsubscribes, either through an email’s unsubscribe link or their mail app’s one-click button. Bounces, complaints, imports, and edits through the API never start one. The trigger picker lists it as When a contact unsubscribes, and Which unsubscribes start it? sets the list it watches:
  • All emails. The contact unsubscribed from everything your brand sends.
  • One marketing domain. Each marketing domain is listed by name. The contact left that domain’s list. An unsubscribe from all, clicked in one of that domain’s emails, starts it too, as long as the contact was still on the list.
Only marketing domains appear. A transactional domain keeps no unsubscribe list, so there is nothing to leave. Brew owns these triggers. A domain’s trigger is named after it, such as Unsubscribed from news.acme.com. The title and payload are fixed, there is nothing to set up, and they can’t be fired over HTTP. The payload is { email, unsubscribe: { scope, domain?, method, reasons, reasonText?, emailId?, emailTitle?, sendId?, at } }. Emails reference it through merge tags such as {{ unsubscribe.domain }} and {{ unsubscribe.reasonText }}. A field marked ? can be absent, and its merge tag then renders blank. domain is missing when the link came from a transactional email. reasons is always there, empty when none was chosen, as after a one-click. A test of the automation runs on Brew’s sample unsubscribe, and any payload fields you pass replace the sample’s. Marketing email from the list the contact left never reaches them. Mail from another marketing domain reaches them only while they are still on that domain’s list. After an unsubscribe from all, no marketing domain does. Brew refuses to publish a flow none of whose emails could reach them. From an agent, ensure_brew_event_trigger returns the brand’s trigger for a scope. The API, SDK, and CLI calls are in From an Agent or Code. To set up a flow on this trigger, see Start a Flow When Someone Unsubscribes.

Manual Audience

A manual-audience automation runs a saved audience through the graph on demand. Its trigger shows the audience, filter query, and contact count. Runs show Sending while in flight and Sent when complete. Manual-audience automations are one-off flows. Choose Run now, Schedule, or Gradual send when launching one. See Send Options for details. The API and MCP also support manual-audience runs, including dry-runs. While a run is in flight, an agent or your code can control it:
  • Pause stops it at the next step. Emails already going out may finish.
  • Resume continues delivery. It also retries a failed run from its first undelivered step, skipping steps that already completed.
  • Cancel stops the remaining steps for good. Emails already delivered stay sent.
A run held at your plan’s send limit resumes on its own. Over MCP these are pause_audience_run, resume_audience_run, and cancel_audience_run.

From an Agent or Code

  • Fire a custom event. POST /v1/automations/triggers/{triggerEventId}/fire. Build an Automation has the request and the error codes.
  • Get the brand’s trigger for a scope. POST /v1/automations/triggers/brew-events from code, brew.automations.triggers.ensureBrewEvent() in the SDK, and brew-cli automations triggers ensure-brew-event in the CLI.
  • Read a trigger’s contract. GET /v1/automations/triggers/{triggerEventId} returns its payloadSchema, the shape the validation error checks against.

Need Help?

Our team is ready to support you at every step of your journey with Brew. Choose the option that works best for you:

Search Documentation

Type in the “Ask any question” search bar at the top left to instantly find relevant documentation pages.

Ask ChatGPT or Claude

Click here to open the Copy page menu at the top of this page, then send the page to ChatGPT, Claude, or your editor.