Waymark decouples journey logic from your frontend and backend code. Define states, transitions, and conditions in structured JSON or YAML — and let the engine handle the rest.
{
"name": "Enterprise Onboarding",
"nodes": [
{ "id": "11111111-1111-1111-1111-111111111111", "key": "user-type", "type": "Form", "isStartNode": true },
{ "id": "22222222-2222-2222-2222-222222222222", "key": "admin-setup", "type": "Form" },
{ "id": "33333333-3333-3333-3333-333333333333", "key": "guest-welcome", "type": "Information" }
],
"connections": [
{
"sourceNodeId": "11111111-1111-1111-1111-111111111111",
"targetNodeId": "22222222-2222-2222-2222-222222222222",
"conditionField": "Role",
"conditionOperator": "Equals",
"conditionValue": "Admin"
},
{
"sourceNodeId": "11111111-1111-1111-1111-111111111111",
"targetNodeId": "33333333-3333-3333-3333-333333333333"
}
]
}
Watch how Waymark dynamically routes users through conditional paths
Every new journey variation means another PR, another deployment, and another round of regression testing. Conditional branches multiply. Business rules bleed into UI code. Engineers become gatekeepers for what should be product decisions.
Waymark evaluates your JSON schema at runtime, resolving the next node for each session based on submitted data and customer profiles. Change journeys without touching source code — no build, no deploy, no rollback risk.
From simple onboarding flows to complex compliance pipelines — Waymark provides the primitives to model any journey.
Define states, transitions, and conditions in JSON or YAML. The engine interprets your schema at runtime — no compilation required.
Integrate via REST API from any platform — React, Vue, React Native, Node.js, or any HTTP client. The engine lives on the backend.
12 condition operators (Equals, GreaterThan, MatchesRegex, …) evaluated against submitted payload or customer profile fields.
Attach server-side validation to any node via complianceRuleJson. Required fields, regex patterns, numeric ranges, and cross-field comparisons.
Built-in DocumentUpload node type with file type filtering, size limits, and progress streaming via SSE.
Real-time events for step-advanced, session-completed, and session-abandoned. Integrate downstream systems without polling.
Drag-and-drop admin UI at /admin/journey-builder. Design flows visually — drag nodes, draw connections, edit properties — without writing JSON.
A journey is a directed graph stored as data. The engine evaluates it at runtime for each session.
POST a JSON document describing nodes (Form, DocumentUpload, Redirect, Information, Logic) and their conditional connections to POST /api/flows.
Call POST /api/workflow/sessions/start with a flowId and optional customerProfileId. The engine returns the first node definition.
Your frontend renders the node using its type and jsonContent. On submit, the engine validates compliance rules and resolves the next node.
When no connection matches, the session is marked Completed. Registered webhooks fire immediately and retry on transient failure.
Session lifecycle
StartSession ──► Started
│
SubmitStep (compliance pass)
│
┌─────────▼──────────┐
│ Logic auto-advance │
└─────────┬──────────┘
│
┌───────────┼────────────┐
│ │ │
next node no next node failOnError
resolved resolved triggered
│ │ │
Started Completed Error
│
AbandonSession
│
Abandoned
Any multi-step, conditional user flow maps naturally onto a Waymark schema.
Admin users see a full KYC flow; guest users are directed to a lightweight welcome sequence. Compliance questionnaires adapt to business size and region.
Route customers to credit card validation or PayPal based on their selection. Cross-field compliance rules enforce amount limits per payment method.
Patient intake forms that branch by insurance type, skip irrelevant sections, and route to external EHR systems via HttpCallback Logic nodes.
From a simple contact form to a conditional payment flow — all expressed as data.
{
"name": "Contact Form",
"nodes": [
{
"id": "11111111-1111-1111-1111-111111111111",
"key": "personal-info",
"type": "Form",
"title": "Your details",
"isStartNode": true,
"jsonContent": "{\"fields\":[{\"name\":\"Name\",\"type\":\"text\",\"required\":true},{\"name\":\"Email\",\"type\":\"email\",\"required\":true}]}"
},
{
"id": "22222222-2222-2222-2222-222222222222",
"key": "message",
"type": "Form",
"title": "Your message",
"jsonContent": "{\"fields\":[{\"name\":\"Subject\",\"type\":\"text\",\"required\":true},{\"name\":\"Body\",\"type\":\"textarea\",\"required\":true}]}"
},
{
"id": "33333333-3333-3333-3333-333333333333",
"key": "confirmation",
"type": "Information",
"title": "Thank you! We'll be in touch within 24 hours."
}
],
"connections": [
{ "sourceNodeId": "11111111-1111-1111-1111-111111111111", "targetNodeId": "22222222-2222-2222-2222-222222222222" },
{ "sourceNodeId": "22222222-2222-2222-2222-222222222222", "targetNodeId": "33333333-3333-3333-3333-333333333333" }
]
}
Five built-in node types cover the full spectrum of journey interactions.
| Type | Description | Key jsonContent fields |
|---|---|---|
Form |
Renders a dynamic form from a field list. Supports text, email, number, select, checkbox, textarea, date. | fields[] — name, type, required, options |
DocumentUpload |
Renders a file picker with type and size enforcement. Files uploaded before step submission. | acceptedFileTypes, maxFiles |
Redirect |
Navigates to an external URL. Supports {{token}} interpolation for sessionId, flowId, customer fields. |
url — supports tokens |
Information |
Displays a message with no submission required. The node title carries the display text. | — (title field on node) |
Logic |
Executes a server-side action automatically. Auto-advances through up to 20 consecutive Logic nodes. | action, field, value, failOnError |
Start with the documentation — set up the engine in minutes with Docker and the .NET 10 SDK.