Workflow Automation
Workflows are SurelyCrm's most powerful feature. They let you automate repetitive tasks by defining a sequence of stages that trigger based on record events, dates, or conditions — all without writing code.
Every workflow is typed by its primary record. A workflow is
built for Customers, Leads, or
Suppliers.
Supplier workflows are persisted against the Company record type.
The record type is chosen when the workflow is created and controls which
records the workflow can run against, which triggers can start it, and which
actions and conditions are available.
Core Concepts
| Term | Definition |
|---|---|
| Workflow | A reusable automation blueprint made of stages |
| Primary Record | The record type the workflow runs against — Customer (default), Lead, or Supplier |
| Stage | A single step in a workflow with an action type and configuration |
| Instance | A running execution for a specific customer, lead, or Supplier |
| Trigger | The event that starts a workflow (manual, scheduled, or event-based) |
| Condition | A logical rule that determines whether a stage should execute |
| Action | What the workflow does at a given stage (send email, update status, etc.) |
Creating a Workflow
- Navigate to Workflows in the sidebar.
- Click Create Workflow.
- Enter a Name and optional Description.
- Choose the Record Type — Customer (default), Lead, or Supplier. The record type is locked once the workflow has stages or is active, so pick it carefully.
- Add stages by clicking Add Stage.
- For each stage, configure:
- Action Type — What this stage does
- Configuration — The details (template, status, field name, etc.)
- Conditions (optional) — Rules that must be met for the stage to run
- Wait Duration (optional) — Delay before this stage executes
- Save the workflow, then click Activate to make it available for use.
Event triggers follow the record type: Lead workflows can be triggered by Lead itself or by its lead-owned child entities — NotificationHistory (when the row belongs to a lead), LeadActivityHistory, LeadCustomFieldValue, LeadTag, LeadTask, and Opportunity. Customer workflows use the customer-compatible entities shown in the trigger list. Supplier workflows use only the Company entity, displayed as Supplier, and only the Added and Modified states. Company Deleted is not available. The entity list for stage conditions remains broader because conditions may refer to related records. Mismatched or unsupported trigger saves are rejected; an older mismatch must be corrected explicitly.
CLI definition management
Tenant administrators can inspect and manage definitions without a browser by
using the API-key authenticated sure-cli workflow commands. Use
workflow list for paged summaries,
workflow get --id for a complete private export, and
workflow apply --file or --data for a complete
replacement. An apply with no id creates an inactive Draft;
an apply with an
existing id preserves lifecycle state and stable stage identities.
Supplier definitions use Company on the wire and
Supplier in staff-facing text.
Use workflow activate --id and
workflow deactivate --id for explicit lifecycle changes.
Activation validates the stored graph and applies Workflow Builder license and
capacity rules. Repeated desired-state calls are safe. Deactivation pauses new
starts and preserves queue rows and running instances, without a licence
check. A pending trigger attempted by the worker while inactive becomes
Failed; reactivation does not retry it. Existing instances read
the current definition, not a versioned snapshot, so sequence live edits
deliberately. These commands never delete definitions, invoke actions, or
contact configured REST targets.
Exports can contain sensitive action configuration. Keep them private, avoid shell history for inline JSON, and recover an uncertain write by inspecting the tenant before issuing another command. See the CLI workflow reference, the Workflow Definition API, and the API/CLI ADR.
Inspect, create, edit, and enable a definition
Use this journey after the server API is deployed and verified, with a matching CLI configured for the intended tenant host and administrative key. For private QA, use an owned fixture with external delivery disabled. These steps manage definitions; starting a Customer/Lead instance is a separate command.
- Run
sure-cli workflow list --page 1 --page-size 50. FollowhasMorewith explicit page requests. Get an existing ID into a private file to inspect its graph and references. - Create a Draft from one of the examples below. Customer is the default;
Lead and Supplier use the same format. Record the returned
idand confirmstatus: Draft,isActive: false. - Get that returned ID into
definition.json. Edit the file and apply it with its workflow ID and existing stage IDs intact. Includestages,trigger, and the exported record type. Read it back, then reapply unchanged to verify the same definition. - Open that definition in the Administrator workflow builder and compare type, graph, trigger, delay, and layout. Legacy graphs without an End node remain readable/reapplicable through the API; the browser can ask for End before saving. Invalid historical rules need explicit correction.
- Activate the returned ID, get it to confirm Active/true, then repeat activation. Deactivate, get it to confirm Paused/false, then repeat deactivation. Repeats create no instances or extra activation slots.
sure-cli workflow apply --data \
'{"name":"Customer draft","primaryEntityType":"Customer","stages":[],"trigger":null}'
sure-cli workflow apply --data \
'{"name":"Lead draft","primaryEntityType":"Lead","stages":[],"trigger":null}'
sure-cli workflow apply --data \
'{"name":"Supplier draft","primaryEntityType":"Company","stages":[],"trigger":null}'
These empty drafts demonstrate creation without delivery actions. Add the intended stages and trigger before operational use; activation requires at least one stage and rejects an empty definition. The following commands use an example ID; replace it with the ID returned by your create.
sure-cli workflow get --id 550e8400-e29b-41d4-a716-446655440000 \
> definition.json
sure-cli workflow apply --file definition.json
sure-cli workflow get --id 550e8400-e29b-41d4-a716-446655440000
sure-cli workflow activate --id 550e8400-e29b-41d4-a716-446655440000
sure-cli workflow deactivate --id 550e8400-e29b-41d4-a716-446655440000
For a live edit, inspect running instances and queued starts first. Deactivation does not freeze instances or safely hold the queue. A retained trigger keeps its ID even when edited, but removing a trigger with any queue references or a stage with execution history fails. Concurrent edits use the last successful whole replacement; there is no stale-edit warning. To make a copy, remove the workflow ID, use available stage IDs, update all edges, and reconcile tenant references. The API-key/CLI surface has no automatic copying by name or deletion.
Action Types
| Action | Description |
|---|---|
| Send Email | Sends an email using a template or custom content |
| Send SMS | Sends an SMS message using a template |
| Send Portal Invitation | Sends the existing portal registration invitation to a Customer; available only in Customer workflows |
| Update Status | Changes the record's status to a new value |
| Set Custom Field | Updates a custom field value for the customer |
| Create Record | Creates a new related record (payment, document, etc.) |
| Start Workflow | Triggers another workflow for the same record |
| Wait | Pauses for a specified duration before continuing |
| InvokeRest (REST API) | Posts configured data to an external URL |
Actions in Customer Workflows
The Customer-only Send Portal Invitation action has no configuration. It creates a fresh registration token when the stage runs and sends the existing portal invitation email. The stage fails with a visible reason when the customer has no email, portal access is disabled, or the customer is already registered.
Actions in Lead Workflows
Lead-typed workflows support a focused set of actions that map onto lead data:
| Action | Behaviour on a lead |
|---|---|
| Send Email | Sends using the lead's contact person, email address, and phone number (welcome and nurture templates) |
| Send SMS | Sends to the lead's contact phone number |
| Update Status | Sets a Lead status selected from the tenant's Lead lookup, such as New → NoResponse. Customer workflows continue to use a Customer-typed status. |
| Wait | Pauses for the configured duration |
| Start Workflow | Starts a child workflow for the same lead; the child workflow must also be Lead-typed |
| REST API | Runs the existing configured REST action |
Status lookup: Both Customer and Lead Update Status stages
store a typed status lookup GUID in statusId. A Lead stage can
select and save only a Lead status; a Customer GUID is invalid even when it
is well formed. Customer stages use Customer-typed statuses.
Existing workflows: If a Lead status stage was previously
saved with a Customer status GUID, its statusId is left
unselected. Choose a Lead status explicitly before saving. SurelyCrm does
not guess a replacement or run the invalid stage automatically. Saving the
correction does not start the workflow or resend an earlier action.
Actions that are not supported for leads — Note, Outbound Call, Inbound Call, Add Tag, Remove Tag, Reset Age, Set Data Field, Set Custom Field, Create Record, and Assign Form — are skipped when they appear in a Lead stage. The stage instance records a clear message ("not supported for lead workflows") and the skip is logged. The existing REST API action is supported for Lead workflows.
Actions in Supplier Workflows
Supplier workflows run against the existing Company record and support this focused action set:
| Action | Behaviour on a Supplier |
|---|---|
| Send Email | Uses the Company contact email and existing email template builder |
| Send SMS | Uses the Company contact number and existing SMS template builder |
| Update Status | Sets one of NA, Pending, Open, Rejected, or Spent |
| Wait | Pauses for the configured duration |
| Start Workflow | Starts a child Supplier workflow for the same Company |
| REST API | Uses the existing REST action; [CompanyId] is substituted in the outbound body only |
Safe skips: Note, Outbound Call, Inbound Call, Add Tag, Remove Tag, Reset Age, Set Data Field, Set Custom Field, Create Record, and Assign Form are marked Skipped with a "not supported for supplier workflows" reason. The instance continues to its next stage.
Email and SMS require the matching Company contact detail. Missing details, transport failures, or a disabled Supplier workflow capability fail the stage safely and retain the existing retry behaviour. Supplier delivery does not create communication history or a new history screen. Failed REST responses use a bounded status reason rather than storing the echoed response content.
Building Conditions
Conditions let you build branching logic into your workflows. You can create rules based on:
- Customer fields (Firstname, Surname, Email, MobilePhone, Postcode, etc.)
- Custom fields
- Status
- Balance amounts
- Age (days since creation)
- Important dates
- Date of birth
- Notifications enabled flag
Conditions support comparison operators such as Equals, Not Equals, Greater Than, Less Than, Contains, and Starts With. You can chain multiple conditions with AND/OR logic.
Conditions in Lead Workflows
Lead-typed workflows evaluate stage conditions against lead fields:
- Status — the lead's current tenant-defined status (for example, New, Processing, or ReadyForEmail)
- Attempt Count — number of contact attempts made
- Business Name — the prospect's business or organisation
- Contact Email / Contact Phone / Contact Person
- Website URL / Preferred Site
- Has Sales Brief — whether a Sales Brief is stored on the lead
- Campaign — the campaign the lead belongs to
- Last Activity Date / Next Eligible At — engagement timing
Lead stage conditions and branch rules also read saved values from active
Lead custom fields. When configuring a definition through the
workflow API or CLI, set
field to the exact custom-field Name, including
its case; labels and prefixes are not used. Built-in names remain
case-insensitive and take precedence over a custom field with the same name,
even when the built-in value is absent.
A missing stored value, unknown name, inactive definition, or field belonging
to another record type evaluates as null. Values come from the current
tenant and use the existing comparison operators. isnull matches
null or an empty string; isnotnull matches a non-empty value.
isempty tests blank or whitespace-only stored text; it does not
match null. No default value is substituted for an absent stored value.
For example, put this JSON in an action's
conditionConfiguration, with conditionMode: Route
and an else target. A match can return the Lead to a configured reply status
and notify staff; the else route can continue the approval. The field name
and routes are tenant configuration:
{
"logicOperator": "AND",
"conditions": [
{ "field": "CustomerHostname", "operator": "isnull", "value": "" }
]
}
The same condition can be placed inside a branch rule. Rules are evaluated in order and the first matching rule wins. Each evaluation reloads the Lead's saved custom values, so later stages and retries see later edits.
Conditions in Supplier Workflows
Supplier stages evaluate the current Company fields available on the Supplier record:
- Name
- Contact Person, Contact Number, and Contact Email
- Address 1 through Address 4, Town, City, and Postcode
- Status
- Credit Limit and Credit Used
- Record Owner
These conditions use the same comparison operators as other workflow conditions. Tenant isolation and record-access restrictions still apply. A missing or inaccessible Supplier does not get changed by a condition check.
Example: A renewal workflow might have a condition "OutstandingBalance > 0 AND Status = Active" to ensure it only runs for active customers who owe money.
Branching and end nodes
The builder is a graph canvas. Alongside action stages you can add:
- Branch — an ordered list of rules, each with conditions and a target stage, plus an otherwise (else) target. Rules are checked top to bottom and the first match wins, expressing "if status = A then X, if B then Y, otherwise Z".
- Wait — pauses the workflow for a set time, then continues. Waiting is its own node rather than an action.
- End — stops the workflow. Use it so a branch can finish the run without executing later stages.
An action can also carry conditions directly. Choose what happens when the conditions are not met:
- Wait until they are met — the action runs once the record matches (the historic behaviour).
- Skip this action and go to... — route to a different stage (or end the workflow) when the condition fails. This is the quickest way to "take a different action when data is in a particular state, or if a condition fails".
Drag nodes to arrange the flow. Action nodes can point at an explicit
Next stage; branch edges are labelled IF and
ELSE. Paths may converge back into a shared stage. Saving validates
that every target exists, that each branch has an otherwise path, and that the
graph has no loops.
Stages keep their identity when you edit a workflow, so running instances stay on track and branch targets keep working. Stages that a run does not reach are marked skipped in the instance history.
Starting Workflows
Workflows can be started in several ways:
- Manually (customer) — From the customer's profile, click Start Workflow and select a Customer-typed workflow
- Manually (lead) — From the lead's Workflows tab, select an active Lead-typed workflow and click Start Workflow
- Manually (Supplier) — From an existing accessible Supplier's Manage page, select an active Supplier workflow and click Start Supplier Workflow
- From Bulk Actions — Select multiple Customers, or
non-converted Leads when
Leadsis enabled, and trigger a workflow of the matching record type - From Another Workflow — Use the "Start Workflow" action to chain workflows together (the child workflow must have the same record type)
- Scheduled — Set up recurring scheduled actions in the Action Designer
- Automatically (customer) — Database triggers on the Customer entity (customer created or modified) start matching Customer-typed workflows
- Automatically (lead) — Database triggers on the Lead entity (lead created or modified) start matching Lead-typed workflows, giving you full automatic enrollment for leads
- Automatically (Supplier) — Company Added or Modified triggers start matching Supplier workflows
- Automatically (Appointment) — Appointment Added triggers start matching workflows when an appointment is booked. Rescheduling an appointment cancels its active instances and queues the trigger again
- Automatically (Invoice) — Invoice Added triggers start matching workflows when an invoice is created, including a draft or auto-generated invoice. Voiding or fully paying an invoice cancels its active instances
The seeded Appointment Confirmation, Appointment Reminder, Invoice Due Reminder, and Invoice Overdue Reminder workflows use a Wait stage relative to the appointment start or invoice due date. A positive offset waits before the date; a negative offset waits after it. If the calculated time has already passed, the instance is cancelled and the reminder is skipped. These workflows are created as drafts with their triggers attached, ready for review and activation. See Appointment workflows and Invoice workflows.
Successful external Lead claims and first sample-site completions also raise
the existing Lead modified event. Filter on
StatusId using the tenant's target Lead status ID. The status
transition and trigger queue writes commit together; conflicting claims and
completion replays add no work. Enable BackgroundEngine,
ProcessWorkflowTriggers and ProcessWorkflows for the
existing worker to start and execute queued workflows. Worker execution and
email delivery remain asynchronous and are not crash-safe exactly-once.
A configured Lead DNS email can use
[Lead.ExtraField.CustomerHostname] for a saved custom field and
[Lead.ExternalReference] in a Lead-identifying link. Use your
tenant's exact custom-field Name and a verified recipient/template; these are
existing template tokens, not mandatory field names or status configuration.
Manual start and triggers are type-aware: a Lead workflow starts only on leads, a Customer workflow only on customers, and a Supplier workflow only on Companies. A Supplier child workflow must also be Supplier-typed. Converted leads (already linked to a customer) remain customer-side — the lead page hides its start form once converted, and Customer workflows are started from the customer record. There is no Supplier API or CLI start surface.
Monitoring Instances
Go to Workflows > Instances to see all running and completed workflow executions. The list shows a Record Type column so you can tell Customer, Lead, and Supplier instances apart. Instance details show the lead or Supplier subject with a link back to its record. For each instance you can:
An instance remains linked to its original Customer, Lead, or Supplier as its stages and status progress, so it stays visible from that record's workflow view.
Ownership maintenance: Source complete — not deployed. Dave owns production CRM deployment. Existing detached instances are not repaired because their original owner cannot be determined safely.
Supplier Email and SMS use the Supplier contact details but do not create communication-history rows or a Supplier history view. Delivery and workflow audit messages use bounded, identifier-free feedback.
- View the current stage and overall status
- See stage-by-stage results and any error messages
- Pause an instance to temporarily halt execution
- Resume a paused instance
- Cancel an instance to stop it permanently
- Advance manually to the next stage (useful for testing)
Example Workflows
Welcome Sequence for New Leads
A Lead-typed workflow with a database trigger on Lead created — every new lead is enrolled automatically:
- Stage 1: Wait 10 minutes
- Stage 2: Send Email — "Welcome" template (uses the lead's contact person and email address)
- Stage 3: Wait 2 days
- Stage 4: Condition — Status still "New"?
- Stage 5: Send SMS — "Follow-up" template (to the lead's contact phone)
- Stage 6: Update Status — "NoResponse"
Payment Reminder
- Stage 1: Condition — OutstandingBalance > 0
- Stage 2: Send Email — "Payment Reminder" template
- Stage 3: Wait 7 days
- Stage 4: Condition — OutstandingBalance > 0
- Stage 5: Send Email — "Final Notice" template
- Stage 6: Update Status — "Payment Due"
Onboarding Tracker
- Stage 1: Send Email — "Welcome Pack"
- Stage 2: Set Custom Field — OnboardingStatus = "Welcome Sent"
- Stage 3: Wait 1 day
- Stage 4: Send Email — "Setup Guide"
- Stage 5: Set Custom Field — OnboardingStatus = "Setup Guide Sent"
- Stage 6: Wait 3 days
- Stage 7: Set Custom Field — OnboardingStatus = "Completed"
Best Practices
- Name workflows clearly — Use descriptive names like "New Lead Welcome — 3 Day" rather than "Workflow 1"
- Test before activating — Run a workflow manually on a test Customer, Lead, or Supplier first
- Use conditions liberally — They prevent workflows from running inappropriately
- Monitor instances regularly — Check for failures and address root causes
- Keep stages focused — One action per stage makes debugging easier