Trigger-action model
Why this matters for your business
Most workflow tools (Zapier, Make, etc.) let you connect any event to any action — flexible but dangerous. A typo in the wiring sends 50,000 customers a "thanks for your order" email when only one ordered. A condition referencing a field that doesn't exist silently fails. The tools are powerful but unsafe; merchants who use them learn to be defensive, slowing everything down.
Sumeru Systems uses a typed trigger-action model. Every trigger declares the data it produces (an order trigger always carries order id, customer id, total, line items, etc.). Every action declares what data it requires. The system validates the connection at save time — you can't wire an "update product price" action onto a "customer subscribed" trigger because the trigger doesn't know which product. Mistakes that would cost real money in ungoverned tools become impossible.
The trade-off: you can do less wild things than in Zapier. The benefit: every rule that runs is rules you intended.
What this typically unlocks
| Outcome | Result |
|---|---|
| Rule mis-fires due to wiring errors | near 0 |
| Time-to-debug a misbehaving rule | minutes vs. hours of "what is this even doing" |
| Confidence in shipping new rules | high — type-checking catches the obvious mistakes |
| Onboarding a new team member to automations | 2 hours to productive use |
The trigger catalog
Every trigger is one of the categories below; each carries a predictable, documented payload.
Customer triggers
| Trigger | Fires when | Payload includes |
|---|---|---|
customer_created | New customer profile created | customer_id, email, phone, source |
customer_updated | Profile field changed | customer_id, changed_fields, old/new values |
customer_tagged | Tag added/removed | customer_id, tag, action |
lifecycle_changed | Lifecycle stage transition | customer_id, from_stage, to_stage |
opt_in_changed | Channel opt-in toggled | customer_id, channel, action |
customer_segment_joined | Customer added to a segment | customer_id, segment_id |
customer_segment_left | Customer removed from a segment | customer_id, segment_id |
Order triggers
| Trigger | Fires when | Payload includes |
|---|---|---|
order_created | New order placed | order_id, customer_id, total, line_items |
order_paid | Payment captured | order_id, payment_method, amount |
order_fulfilled | Order shipped | order_id, fulfillment, tracking |
order_cancelled | Order cancelled | order_id, reason, refund_amount |
refund_created | Refund processed | order_id, refund_amount, reason |
repeat_order_milestone | Customer's Nth order (configurable N) | customer_id, order_count |
Product / inventory triggers
| Trigger | Fires when | Payload includes |
|---|---|---|
product_created | New product | product_id, title, type |
product_updated | Field changed | product_id, changed_fields |
product_sold_out | Inventory hits 0 | product_id, sku, last_buyer |
product_restocked | Inventory back from 0 | product_id, sku, qty |
low_stock_alert | Stock below threshold | product_id, sku, qty, threshold |
Marketing triggers
| Trigger | Fires when | Payload includes |
|---|---|---|
campaign_launched | Campaign goes live | campaign_id, audience_size |
campaign_completed | Campaign + attribution window done | campaign_id, revenue, lift |
journey_enrolled | Customer entered a journey | journey_id, customer_id, step |
journey_exited | Customer left a journey | journey_id, customer_id, exit_reason |
message_opened | Email/WhatsApp/SMS opened | message_id, customer_id, channel |
message_clicked | Click on link | message_id, customer_id, link |
External + time-based triggers
| Trigger | Fires when |
|---|---|
webhook_received | External HTTP POST arrives |
zapier_event | Event from Zapier integration |
cron_schedule | Time-based (daily/weekly) |
anomaly_detected | Anomaly detector fired |
The action catalog
| Action category | Examples |
|---|---|
| Customer | tag / untag, update_field, enroll_journey, exit_journey, send_transactional_email |
| Marketing | send_campaign, sync_to_meta_audience, sync_to_google_audience, post_to_slack |
| Catalog | update_price, update_inventory, hide_product, change_sku, generate_alt_text (AI) |
| External | fire_webhook, post_zapier, create_airtable_row, post_to_make |
| AI (Pro+) | generate_copy, suggest_segment, predict_churn, run_recommendation |
| Workflow | run_rule (chain), wait, branch_by_condition |
How types prevent mistakes
Three checks run when you save a rule:
- Trigger payload includes required fields. "Update price"
action needs a
product_id; "customer_created" trigger doesn't have one. Save fails, error explains why. - Conditions reference real fields. Typo in
Customer360.lifecycelStage(sic) catches at save, not at first fire. - Cycle detection. Rule A fires rule B fires rule A → save fails. Prevents infinite loops.
The result: the rules you save are the rules that work. No silent failures, no misfires.
Real merchant scenarios
Scenario A — Customer-tag → journey-enroll chain
A common composition pattern. Trigger: customer_tagged (tag
= vip). Action: enroll_journey (journey_id = vip-welcome).
When marketing manually tags a customer or the predictive-LTV auto-rule tags them, the welcome journey fires immediately. Two simple rules; one composable workflow.
Scenario B — Refund anomaly auto-pause
Trigger: anomaly_detected (kpi = refund_rate, severity = P1).
Action: post_to_slack (channel = #urgent) + enroll_journey
(journey for affected products' customers).
Catches refund spikes (often signaling product quality issues) in real time.
Scenario C — External webhook → internal flow
Trigger: webhook_received (path = /zapier/new-shopify-app).
Action: update_field (Customer360, custom_field_app_install_date).
Lets external Zaps drive Sumeru Systems rules without writing code.
Best practices
✅ Read the payload spec for triggers you use. "What can I actually do with this?" answered upfront.
✅ Test new actions in dry-run mode first. Especially catalog/external actions where mistakes are costly.
❌ Don't try to wire "any event → any action" Zapier-style. The type system will reject most of those; respect what it's telling you.
❌ Don't write conditions referencing fields that might not exist. The type system catches the obvious cases; rare edge cases (a never-set custom field) can still trip up rules.
Plan tiers
| Capability | Free | Starter | Pro | Agency | Enterprise |
|---|---|---|---|---|---|
| Built-in trigger catalog | ✓ | ✓ | ✓ | ✓ | ✓ |
| Custom-field triggers | — | ✓ | ✓ | ✓ | ✓ |
| AI actions | — | — | ✓ | ✓ | ✓ |
| Multi-step chains | — | — | ✓ | ✓ | ✓ |
| Cycle detection | ✓ | ✓ | ✓ | ✓ | ✓ |
| Custom action SDK (extend) | — | — | — | — | ✓ |