Direction Map (TL;DR)
Until outbound webhooks ship, the supported “wait for completion” pattern is polling. See Async jobs & polling.
Inbound: You Call Brew
Pattern: Fire a Custom Event
The canonical agent / backend integration path:payload.emailis the contact key. Every trigger’spayloadSchema.fieldsMUST declare{ key: 'email', type: 'string', required: true }. The fire endpoint also auto-upserts the contact derived from the resolved payload: declaredfirstName/lastName/subscribedland in core columns; everything else lands incustomFields[key](with the field definition auto-created on the brand).Idempotency-Keyis mandatory in practice. A double-fired webhook = doubled emails. See Idempotency.- The fire endpoint returns the legacy fire envelope (
200) withdetails.automationRunIds[]. It’s the one v1 endpoint that wraps both success and failure in this shape. Don’t block on delivery. Poll the run with Async jobs & polling. - At least one bound automation must be Published. Triggers are always-on, but emails only fire when at least one bound automation has
published: true. If every bound automation is in Draft, the fire call returns422 NO_PUBLISHED_AUTOMATION. Publish the automation in the builder (or viabrew.automations.patch({ published: true })) and retry.
Pattern: Integration-Provisioned Triggers
For events that originate inside another product (Clerk’suser.created, Stripe’s customer.subscription.deleted, Shopify’s orders/paid, etc.), Brew can RECEIVE the integration’s webhook directly (no code on your side).
Setup is per-integration in the dashboard (the receiver URL is hosted at /api/integrations/<provider>/webhook/<connectionId>). Once configured, the integration’s events appear in GET /v1/automations/triggers with provider: 'clerk' | 'stripe' | 'shopify' | … and fire your published automations exactly like custom brew_api triggers.
You can bind any of these to an automation. Supported providers today:
Each provider’s adapter normalizes into a flat
{ email, …provider-specific fields } payload that flows through the same fire pipeline as brew_api triggers. Inbound integration webhooks also auto-upsert the contact using a richer per-provider mapper that lands under flat <provider>_* custom field names (e.g. clerk_user_id, stripe_customer_id).
Outbound Webhooks (Roadmap)
We’re shipping outbound webhooks so your backend can be notified when emails are delivered, opened, clicked, bounced, or marked as spam, and when automation runs complete or fail. Below is the planned contract; nothing here is live yet. Subscribe to the changelog for the launch announcement.Planned Event Types
Planned Delivery Contract
- Signed. Every webhook will carry an HMAC signature header (
X-Brew-Signature) and a timestamp (X-Brew-Timestamp) so you can verify origin. - Retried. Exponential back-off (1s / 5s / 30s / 5m / 1h / 6h) until a 2xx response, then dropped after 24h.
- Per-subscription delivery logs. Inspect deliveries + replay failed ones from the dashboard.
- Idempotent. Every event carries a unique
event.id; consumers should dedupe.
Planned Subscription Management API
Planned Envelope
What to Do Today
Security Checklist (Will Apply When Outbound Webhooks Ship)
- Verify the HMAC signature on every webhook (header
X-Brew-Signature). - Treat the timestamp as a freshness check: reject deliveries older than 5 minutes.
- Dedupe on
event.id: Brew may retry on2xxslowness or your own brief outage. - Return
2xxonly when you’ve persisted enough state to survive a restart; return4xxfor permanent rejections so we don’t retry.
See Also
- Authentication: how
Authorization: Bearerworks on the inbound side. - Async jobs & polling: the supported “wait for completion” pattern today.
- Idempotency: pair with every inbound retry.
- Integrations: set up provider receivers (Clerk, Stripe, Shopify, …).
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:- Self-Service Tools
- Talk to Our Team
Search Documentation
Type in the “Ask any question” search bar at the top left to instantly find relevant documentation pages.
ChatGPT/Claude Integration
Click “Open in ChatGPT” at the top right of any page to analyze documentation with ChatGPT or Claude for deeper insights.