Skip to content
Sendora Cloud
Create account
Grow

Automation

Event-triggered DAGs across email / push / SMS / webhook / branch / wait / ai_action / update_profile. Visual builder mirrors API shape 1:1. IaC bundles for import / export.

Features

  • **8 starter blueprints** in the template gallery — welcome series, cart abandonment, order confirmation, post-purchase feedback, trial ending, re-engagement, birthday, password reset. Clone in one click.
  • **Event-typed trigger** — `{ eventType, filters }` with wildcard matching. Any event from any module (auth.user_created, csat.detractor, push.delivered, kb.article_viewed, …) can fire a workflow. Filters narrow by event properties.
  • **8 step types** — `send_email`, `send_push`, `send_sms`, `webhook`, `update_profile`, `wait`, `branch`, `ai_action`. Each implemented in `apps/backend/src/modules/automation/step-executor.ts`.
  • **AI step type** — `ai_action` step with `feature: generate | decide | extract` via gpt-oss:120b / ministral:14b on Ollama Cloud (or BYOK per-org).
  • **Branching** — branch step jumps to ifTrue / ifFalse indexes based on profile trait equality. Standalone delay via `wait` step.
  • **Run history** — filter by status (running / paused / completed / failed), cancel an in-flight run, drill into per-step outcomes + audit log.
  • **Pause / resume mid-flight** — flips `workflow_runs.status` to `paused`; new triggers queue; resume picks up at next step.
  • **Promote.failed webhook** + delivery-health metrics in Health module — broken journeys surface, not silently rot.
  • **Real audience targeting** — Audiences from Customers module evaluate at send-time inside the email/push/sms steps. Real-time audience membership; no nightly CDP sync.

Common use cases

  • Replace Customer.io / Iterable for event-driven lifecycle journeys where the branch + send happens over Sendora-emitted events directly.
  • Cross-channel campaigns (Push → wait 1h → Email → wait 3d → SMS) without stitching three vendors and three reputations — same `user_id` across all 4 sender step types.
  • AI-driven personalization — `ai_action: generate` drafts an email body inline, `decide` picks the next branch, `extract` writes a profile trait, all inside the workflow.

Key concepts

Workflow step types
`email`, `push`, `sms`, `webhook`, `branch` (ifTrue / ifFalse jump), `wait`, `ai_action`, `update_profile`.
Template interpolation
`{{ user.email }}` / `{{ event.amount }}` / `{{ profile.plan }}` resolved per-recipient at step run.
Bundle export
JSON bundle of workflows + audiences for IaC. Diffable. Import roundtrip-stable.

Workflows

Trigger a workflow from any SDK event

FREE

Workflows subscribe to event names. Fire the matching `track()` call from any SDK and the workflow runs server-side — no extra API needed. Workflows are per-project (ADR-013): event's projectId scopes which workflows fire.

// Workflow trigger: { eventType: "checkout_completed" }
sendora.track("checkout_completed", { amount: 49.99 });

Create a workflow

STARTER+

Define triggers + steps via API instead of the visual builder. Step types: `send_email`, `send_push`, `send_sms`, `update_profile`, `webhook`, `branch`, `wait`, `ai_action`. Each step's `config` shape is type-specific.

curl -X POST https://api.sendoracloud.com/api/v1/orgs/<ORG_UUID>/automation/workflows \
  -H "x-api-key: pk_prod_…" \
  -d '{
    "name": "Welcome series",
    "trigger": { "eventType": "user.signed_up" },
    "isActive": true,
    "steps": [
      { "type": "send_email", "config": { "templateId": "<TEMPLATE_UUID>", "to": "{{event.userEmail}}" } },
      { "type": "wait", "config": { "reason": "let user finish onboarding" }, "delayMinutes": 1440 },
      { "type": "send_push", "config": { "title": "Tips for day 1", "body": "{{user.firstName}}, here are 3 tips..." } }
    ]
  }'

Step `config` shapes

STARTER+

Per-step-type config schema. Templates use `{{handlebars}}` substitution against trigger context (`{{event.*}}`, `{{user.*}}`, `{{trait.*}}`).

# send_email   { templateId, to } OR { subject, bodyHtml, to }   — BYOD verified domain required
# send_push    { title, body }                                          — fans out to ctx.userId's tokens
# send_sms     { to, body }                                              — Twilio configured required
# update_profile { traits: { ... } }                                    — merges into ctx.user profile
# webhook      { url, method?, headers?, body? }                        — HMAC-signed; SSRF-guarded
# branch       { condition: { trait/event, op, value }, ifTrue, ifFalse } — jumps to step label
# wait         { reason? } + delayMinutes                               — uses workflow_runs.next_step_at
# ai_action    { flavor: "generate"|"decide"|"extract", prompt, saveTo? } — Ollama Cloud, jsonMode optional

Dry-run a workflow

STARTER+

Send a sample event through the engine without writing rows or firing side effects — returns a step-by-step trace for debugging. EDITOR role required.

curl -X POST https://api.sendoracloud.com/api/v1/orgs/<ORG_UUID>/automation/workflows/<WORKFLOW_UUID>/test-run \
  -H "x-api-key: pk_prod_…" \
  -d '{
    "eventType": "checkout_completed",
    "properties": { "amount": 49.99 }
  }'

Query workflow runs

STARTER+

Inspect each run's step trace + outcome. Per-step outcomes: `sent | suppressed | ai_unavailable | ai_pending | error | skipped-missing-config | byod_required | rate_limited`.

# List
curl 'https://api.sendoracloud.com/api/v1/orgs/<ORG_UUID>/automation/runs?workflowId=<WORKFLOW_UUID>&pageSize=20' \
  -H "x-api-key: pk_prod_…"

# Detail (full step trace)
curl https://api.sendoracloud.com/api/v1/orgs/<ORG_UUID>/automation/runs/<RUN_UUID> \
  -H "x-api-key: pk_prod_…"

Export / import workflow bundles (IaC)

STARTER+

Versioned bundle format for git-tracking workflows + CI promotion (dev → staging → prod). Importer is idempotent by name. Bundle includes `$schema` URL for VS Code autocomplete + validation.

# Export single workflow
curl https://api.sendoracloud.com/api/v1/orgs/<ORG_UUID>/automation/workflows/<WORKFLOW_UUID>/export \
  -H "x-api-key: pk_prod_…" > welcome-series.workflow.json

# Export every workflow in a project
curl 'https://api.sendoracloud.com/api/v1/orgs/<ORG_UUID>/automation/workflows/export?projectId=<PROJECT_UUID>' \
  -H "x-api-key: pk_prod_…" > all.workflows.json

# Import (idempotent — same name updates, new name creates)
curl -X POST 'https://api.sendoracloud.com/api/v1/orgs/<ORG_UUID>/automation/workflows/import?projectId=<PROJECT_UUID>' \
  -H "x-api-key: pk_prod_…" \
  -H "Content-Type: application/json" \
  -d @welcome-series.workflow.json

Related