Workflow Module
This guide is specific to Web SDK 2.0. If you are still using 1.x, you can find documentation here. We strongly recommend upgrading - contact your Incode Representative for upgrade information.
The Workflow module runs server-driven multi-step workflows where step ordering and configuration come from the backend per session. Unlike the dashboard-defined Flow, a Workflow lets the server emit nodes dynamically — including custom-module nodes that callbacks back into your code.
Follows the composite / orchestrator pattern, with an additional
asyncResolutionstate for server-side processing nodes. See the patterns page for the shared lifecycle.
Tag
<incode-workflow> is a standard Web Component. Importing the UI subpath registers the custom element; importing the CSS applies the module's styles.
import '@incodetech/web/workflow';
import '@incodetech/web/workflow/styles.css';Properties
| Property | Type | Required | Description |
|---|---|---|---|
config | WorkflowConfig | ❌ | Workflow configuration (server-driven) |
onFinish | () => void | ❌ | Called when the workflow completes |
onError | (error: string) => void | ❌ | Called when an error occurs |
Configuration
WorkflowConfig is fetched from the backend via GET /omni/workflow/info:
type WorkflowConfig = {
id: string;
name: string;
redirectDesktopToMobile: boolean;
disableSmsOption?: boolean;
addContinueToDesktop?: boolean;
qrPhishingResistance?: boolean;
disableUnsupportedBrowserScreen?: boolean;
oauth2Secured?: boolean;
ds?: boolean; // Deepsight enabled
mergeSessionRecordings?: boolean;
ageAssurance?: boolean;
disableLaunchScreen?: boolean;
};The shape is largely informational — the workflow nodes themselves drive what runs. The boolean flags propagate to sub-modules (e.g., mergeSessionRecordings and ageAssurance to ID Capture; ds to Selfie).
disableLaunchScreen controls the SDK's built-in launch / home screen. When the backend sets it to true, the SDK skips the launch screen and goes straight to the first workflow node. When false (or omitted), the workflow surfaces a homeScreen.visible === true state — the consumer must render the launch screen and call continueFromHome() on user confirmation.
State machine
WorkflowState is a discriminated union over status. idle, loading, and ready additionally carry a homeScreen: { visible: boolean; isContinueLoading: boolean } property — see Launch screen below.
| Status | Description | Properties |
|---|---|---|
idle | Initial state before load() | homeScreen |
loading | Fetching the next node from the workflow server | homeScreen |
ready | Current WorkflowNode is active. Render the corresponding sub-module. | workflowConfig, currentNode, config, moduleState, homeScreen |
asyncResolution | Server is processing async; UI shows progress until the next node arrives. | workflowConfig, currentNode |
finished | Terminal — workflow's last node was a FINISH node. | workflowConfig, finishStatus |
closed | User dismissed | – |
error | Fatal error | error, errorCode? |
Launch screen
When the backend does not set WorkflowConfig.disableLaunchScreen, the workflow exposes a launch / home screen overlay before running the first node. The overlay is signalled via state.homeScreen.visible:
- Render your launch screen when
homeScreen.visible === true. - Call
manager.continueFromHome()on user confirmation;homeScreen.isContinueLoadingbecomestruewhile the orchestrator finishes loading the first module. - When
disableLaunchScreenistrue, the SDK never setshomeScreen.visibleand you can skip rendering the overlay entirely.
Each WorkflowNode carries:
type WorkflowNode = {
id: string;
nodeType: 'MODULE' | 'FINISH' | 'ASYNC_RESOLUTION';
moduleKey: string; // e.g., 'PHONE', 'SELFIE', 'CUSTOM_MODULE'
moduleConfiguration: Record<string, unknown>;
status: string;
workflowId: string;
};API methods
| Method | Description |
|---|---|
load() | Start loading the workflow configuration and the first node from the backend. Call once. |
completeModule() | Mark the current module as complete. Call from the active module's onFinish callback to advance to the next node. |
errorModule(error) | Mark the current module as failed and transition the workflow to a terminal error state. |
completeFlow() | Skip remaining nodes and go straight to the completion step. Used when the workflow was completed externally — e.g. via the desktop → mobile redirect handoff. |
continueFromHome() | Advance past the SDK's launch / home screen. Only meaningful when state.homeScreen.visible === true; no-op otherwise (e.g. when disableLaunchScreen is true). |
getModuleConfig<T>() | Returns the current node's moduleConfiguration merged with workflow-level flags (ds). Typed via the generic parameter. |
getState() | Get the current workflow state synchronously. |
subscribe(callback) | Subscribe to workflow state changes (returns an unsubscribe function). |
Plus the universal manager lifecycle: reset, stop.
Custom module callback
Workflows can include CUSTOM_MODULE nodes that hand control back to your code. Wire a CustomModuleCallback to handle them — it receives interviewId, nodeId, and the configured name, plus onSuccess / onError hooks that advance the workflow.
import { createWorkflowManager } from '@incodetech/core/workflow';
const manager = createWorkflowManager({
config: { /* WorkflowConfig fetched server-side */ },
customModuleCallback: ({ interviewId, nodeId, name, onSuccess, onError }) => {
// Run your custom logic here, then call one of:
onSuccess('Custom check passed');
// or onError('Something went wrong');
},
});See also
- IncodeFlow Component: the dashboard-driven flow alternative
- Module Patterns → composite
- Headless Mode → Orchestrated Flow Manager
- Individual Modules
Updated 22 days ago
