Building your first workflow
The Forge canvas, trigger types, piece library, and common workflow patterns.
Workflows are the core of Apexium's automation. A workflow is a graph of pieces — triggers fire the workflow; actions execute steps; branches + loops compose into business logic. The Forge canvas is the visual editor where you build, edit, and publish workflows.
Forge canvas overview
Head to Workflows → New workflow (or Forge in the sidebar). The canvas has three areas:
- Piece library (left) — every available piece (HTTP, email, SMS, branch, loop, third-party integrations). Drag onto the canvas to add a node.
- Canvas (center) — the workflow graph. Drag nodes to position; click edges to delete; click a node to configure.
- Properties panel (right) — opens when you click a node. Configure props, view sample data, see input expressions.
Every workflow has exactly one trigger node (entry point) + zero or more action nodes. The trigger is typed: form submission, manual button, scheduled cron, or webhook.
Trigger types
Form submission
Fires when a contact submits a form built in Apexium's form designer. Trigger config picks the specific form. The form's submission data flows into the workflow as {{trigger}} — fields are accessible as {{trigger.email}}, {{trigger.first_name}}, etc.
Use case: lead-magnet sign-up form fires a workflow that tags the contact, sends a welcome email, and waits 3 days before the first nurture touch.
Manual
Fires when an admin clicks a button on a contact's profile page. The selected contact flows in as {{trigger.contact}} — the workflow acts on that one contact.
Use case: "Send pre-call brief" — an admin clicks the button on a prospect's profile; the workflow generates a Claude summary of the contact's history and emails it to the rep.
Scheduled (cron)
Fires on a recurring cron expression (every hour, daily at 9am, weekly on Monday, etc.). Has no trigger payload — the workflow queries data itself.
Use case: "Daily stale-lead check" — runs at 8am daily, queries contacts that haven't been touched in 30 days, applies a reactivation tag.
Webhook
Fires when an external system POSTs to a generated URL. Common pattern: Stripe webhooks, Calendly bookings, Zapier zaps.
Use case: "Stripe payment received" — a webhook from Stripe fires the workflow with the payment details; the workflow updates the contact's lifecycle_stage to customer and triggers a thank-you email.
Piece library
Apexium ships with built-in pieces and integration pieces:
Built-in primitives:
- HTTP request — POST/GET to any URL; useful for custom integrations
- Branch — conditional split based on an expression (
{{contact.tier}} == "enterprise") - Loop — iterate over an array (
{{trigger.line_items}}) - Delay — wait N minutes/hours/days before the next step
- Delay until approval — pauses the workflow until a human clicks an approve link
Communication pieces:
- Send email (Apexium) — uses your configured FROM identity; tracks opens + clicks
- Send SMS (Twilio) — requires Twilio credentials configured under Settings → Channels
- Send chat message — Slack, Discord, Microsoft Teams (when channel credential set)
CRM pieces:
- Create contact — adds a new contact (deduped on email)
- Update contact — patches fields (custom fields jsonb merge)
- Apply tag / Remove tag — tag operations
- Create deal — adds to a pipeline stage
Integration pieces:
- Stripe — create customer / charge / cancel subscription
- Google Calendar — create event / check availability
- Gmail — send email through user's Gmail (requires OAuth)
- Slack — post to channel / DM user
Each piece's properties panel documents required inputs + expected outputs.
Common workflow patterns
Lead nurture sequence
Form submitted (lead magnet)
→ Create or update contact (apply tag: "lead-jan")
→ Send email: "Welcome + here's your guide"
→ Delay 3 days
→ Branch: did they open the welcome email?
→ If YES: Send email "Want to chat?"
→ If NO: Send email "Did you get a chance to read..."
→ Delay 7 days
→ Apply tag: "nurture-complete"
Reactivation campaign
Scheduled trigger (daily at 8am)
→ Loop over contacts with last_activity_at < 30 days ago
→ Apply tag "reactivation-attempt-1"
→ Send email: "Haven't heard from you — anything we can help with?"
→ Delay 14 days
→ Branch: did they reply / open?
→ If YES: Apply tag "reactivated"
→ If NO: Apply tag "dormant"
Webhook-driven sync
Webhook trigger (Stripe payment_intent.succeeded)
→ Update contact: lifecycle_stage = "customer"
→ Update contact: custom_fields.lifetime_value += amount
→ Send email: "Thanks for the order"
→ Branch: is this their first order?
→ If YES: Apply tag "new-customer" + trigger "first-week onboarding" workflow
Publishing workflows
A workflow is in one of three states:
- Draft — visible to admins; doesn't execute. Editable freely.
- Published — frozen at a version; trigger is active; executions create runs.
- Archived — disabled; doesn't execute; preserved for audit.
To publish: click Publish in the canvas toolbar. Publishing snapshots the current definition into a workflow_versions row + flips the workflow's status to active. Published versions are immutable (Watch-point D discipline). To edit a published workflow, you create a new draft (the Forge canvas does this automatically when you start editing); your edits land as draft v2 until you publish again.
Testing workflows
The Forge canvas has a "Test" mode that runs the workflow against a sample payload without sending real emails / SMS / Stripe charges. Sample data is auto-generated for each trigger type; you can edit it before running.
For end-to-end testing with real side effects: publish the workflow + trigger it against a test contact (e.g., create a contact with your own email + manually fire the trigger). View the run in Workflows → [workflow] → Runs — every step's input/output/error is recorded for debugging.
What to do next
- Browse the 10 starter templates at Workflows → New from template to see common patterns built out.
- Set up the Lead Harvester to feed continuous leads into a nurture workflow.
- If you're sending email, configure your sending channel properly first.