Skip to main content

About Automation Triggers

Brew automations are triggered via API, giving you complete control over when workflows run and what data is passed to them. Each automation has a unique ID and a typed payload schema that defines the data structure expected when triggering.
For information about building automation workflows (nodes, timing, branching), see the Automations page.

Triggering Automations

Trigger a specific automation by ID with a validated payload:
curl -X POST "https://brew.new/api/automations/YOUR_AUTOMATION_ID/trigger" \
  -H "Authorization: Bearer brew_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "payload": {
      "email": "customer@example.com",
      "firstName": "John",
      "orderId": "ORD-12345",
      "orderTotal": 99.99
    }
  }'
Response:
{
  "success": true,
  "executionId": "exec_abc123",
  "automationId": "YOUR_AUTOMATION_ID",
  "eventId": "order_placed",
  "status": "running",
  "contact": {
    "email": "customer@example.com",
    "action": "created"
  }
}

Contact Upsert on Trigger

When you trigger an automation via API, Brew automatically:
  1. Looks up the contact by the email field in your payload
  2. Creates a new contact if none exists, or updates the existing contact with payload data
  3. Returns the action taken in the response ("action": "created" or "action": "updated")
This means you don’t need to separately import contacts before triggering automations. Any data in your payload (like firstName, custom fields) is automatically saved to the contact record.
The email field is always required at the root level of your payload. Brew uses this to identify the contact.

Configuring Event Triggers

When creating an automation in Brew, you define the event trigger with:
  1. Event ID - A unique identifier (e.g., order_placed, user_signup)
  2. Event Name - A human-readable display name
  3. Payload Schema - The expected data structure with field types

Payload Schema

Define the data your automation expects. Each field has:
  • Type: string, number, boolean, object, or array
  • Required: Whether the field must be present
  • Description: Documentation for the field
Example schema (keep it flat and minimal):
{
  "properties": {
    "email": { "type": "string", "description": "Recipient email address (required)" },
    "firstName": { "type": "string", "description": "Customer first name" },
    "orderId": { "type": "string", "description": "Order identifier" },
    "orderTotal": { "type": "number", "description": "Order total in dollars" }
  },
  "required": ["email"]
}

Payload Validation

When you trigger an automation, Brew validates the payload against the schema:
  • Required fields must be present
  • Field types must match (string, number, boolean, etc.)
  • Nested objects and arrays are recursively validated
If validation fails, the API returns a 400 error with details:
{
  "error": {
    "code": "INVALID_PAYLOAD",
    "message": "Payload validation failed",
    "details": [
      { "field": "orderId", "message": "Required field \"orderId\" is missing" },
      { "field": "orderTotal", "message": "Field \"orderTotal\" must be a number" }
    ]
  }
}

Using Payload Data in Emails

Access trigger payload data in your email templates using the @trigger:output.payload variable prefix:
Payload FieldTemplate Variable
email{{@trigger:output.payload.email}}
firstName{{@trigger:output.payload.firstName}}
orderId{{@trigger:output.payload.orderId}}
orderTotal{{@trigger:output.payload.orderTotal}}
items[0].name{{@trigger:output.payload.items.0.name}}
When creating automations with AI, Brew automatically suggests relevant template variables based on your payload schema.

SDK Examples

import BrewSDK from 'brew-sdk';

const client = new BrewSDK({ apiKey: "brew_YOUR_API_KEY" });

// Trigger an automation with a flat payload
const result = await client.automations.trigger("auto_abc123", {
  email: "customer@example.com",
  firstName: "John",
  orderId: "ORD-12345",
  orderTotal: 99.99,
});

console.log(result.contact.action); // "created" or "updated"

Getting Automation Info

Retrieve an automation’s trigger configuration:
curl "https://brew.new/api/automations/auto_abc123/trigger" \
  -H "Authorization: Bearer brew_YOUR_API_KEY"
Response:
{
  "automationId": "auto_abc123",
  "name": "Order Confirmation Flow",
  "status": "active",
  "isEnabled": true,
  "isPublished": true,
  "eventDefinition": {
    "eventId": "order_placed",
    "eventName": "Order Placed",
    "payloadSchema": {
      "properties": {
        "email": { "type": "string" },
        "firstName": { "type": "string" },
        "orderId": { "type": "string" },
        "orderTotal": { "type": "number" }
      },
      "required": ["email"]
    },
    "samplePayload": {
      "email": "customer@example.com",
      "firstName": "John",
      "orderId": "ORD-12345"
    }
  },
  "endpoint": "/api/automations/auto_abc123/trigger"
}

Common Use Cases

Below are real-world examples showing how to integrate automation triggers into your application. For complete SDK documentation with error handling and advanced patterns, see:

Welcome Email on Signup

Trigger a welcome sequence when a user creates an account:
import BrewSDK from 'brew-sdk';

const client = new BrewSDK();

// In your signup handler
async function onUserSignup(user: User) {
  await client.automations.trigger("auto_welcome", {
    email: user.email,
    firstName: user.firstName,
    plan: user.plan,
    signupSource: user.referrer || "direct",
  });
}

Order Confirmation

Send order details after a purchase:
async function onOrderComplete(order: Order) {
  const result = await client.automations.trigger("auto_order_confirm", {
    email: order.customerEmail,
    firstName: order.customerName.split(' ')[0],
    orderId: order.id,
    orderTotal: order.total,
    itemCount: order.items.length,
  });

  console.log(`Contact ${result.contact.action}`); // "created" or "updated"
}

Payment Failed Recovery

Prompt users to update payment info:
async function onPaymentFailed(subscription: Subscription) {
  await client.automations.trigger("auto_payment_failed", {
    email: subscription.customerEmail,
    firstName: subscription.customerName,
    amount: subscription.amount,
    retryUrl: `https://app.example.com/billing/retry/${subscription.id}`,
    attemptNumber: subscription.failedAttempts,
  });
}

Trial Ending Reminder

Notify users before their trial expires:
// Run daily via cron job
async function checkTrialsEnding() {
  const users = await db.users.findMany({
    where: { trialEndsAt: { lte: addDays(new Date(), 3) } }
  });

  for (const user of users) {
    await client.automations.trigger("auto_trial_ending", {
      email: user.email,
      firstName: user.firstName,
      daysRemaining: differenceInDays(user.trialEndsAt, new Date()),
      upgradeUrl: `https://app.example.com/upgrade?user=${user.id}`,
    });
  }
}

Common Event Types

Event IDDescriptionCommon Payload Fields
user_signupNew user registrationemail, firstName, plan, signupSource
order_placedE-commerce purchaseemail, firstName, orderId, orderTotal
subscription_startedNew subscriptionemail, firstName, plan, billingCycle
payment_failedPayment retry neededemail, firstName, amount, retryUrl
trial_endingTrial expiration noticeemail, firstName, daysRemaining, upgradeUrl
milestone_reachedUser achievementemail, firstName, milestone, achievedAt

Best Practices

Choose clear, specific event IDs that describe the action:Good: order_placed, user_signup, subscription_renewedAvoid: event1, trigger, action
Always configure your payload schema in the automation builder before triggering via API. This ensures:
  • Payload validation catches errors early
  • Template variables are available in the email editor
  • API documentation is accurate in the publish dialog
The email field must ALWAYS be at the root level of your payload (never nested). Brew uses this to:
  • Automatically create or update the contact
  • Send emails to the right recipient
  • Enable tracking and analytics
  • Look up contact data for personalization
Avoid nested objects in your payload when possible:Good (flat):
{ "email": "...", "firstName": "John", "orderId": "123" }
Avoid (nested):
{ "user": { "email": "...", "name": "John" }, "order": { "id": "123" } }
Flat payloads are easier to map to contact fields and use in email templates.
Implement error handling for common scenarios:
  • 400 INVALID_PAYLOAD - Fix payload data and retry
  • 400 AUTOMATION_NOT_ACTIVE - Check automation status in Brew
  • 401 UNAUTHORIZED - Verify API key
  • 404 AUTOMATION_NOT_FOUND - Check automation ID
For important automations (like order confirmations), include an idempotency key:
-H "Idempotency-Key: order-ORD-12345"
This prevents duplicate emails if your request is retried.

Testing Automations

1

Preview in Brew

Use the publish dialog to preview API code snippets with your actual automation ID and payload schema.
2

Test with example.com

Send test triggers with @example.com or @test.com email addresses - no real emails will be sent.
3

Monitor executions

View automation runs in the Brew dashboard to verify your triggers are working correctly.

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.

ChatGPT/Claude Integration

Click “Open in ChatGPT” at the top right of any page to analyze documentation with ChatGPT or Claude for deeper insights.