This example demonstrates marktoflow's human-in-the-loop functionality using form-based approval steps.
- ✅ Wait Step with Form Mode - Pauses workflow execution for human input
- ✅ Form Field Types - Select dropdown, text area, and string input
- ✅ Conditional Logic - Different actions based on approval decision
- ✅ Form Data Access - Access submitted form data via
{stepId}_responsevariable
- Submit Expense - Workflow starts with employee name, amount, and category
- Wait for Approval - Workflow pauses and presents a form to a reviewer
- Form Submission - Reviewer approves/rejects with optional comments
- Process Decision - Workflow resumes and processes the decision
- Set Outputs - Final status and comments are saved as workflow outputs
marktoflow run examples/approval-workflow/workflow.md \
--input employee_name="John Doe" \
--input amount=250 \
--input category="Travel"- Start the GUI server:
marktoflow gui - Open http://localhost:3001
- Navigate to the workflow
- Click "Execute" and provide inputs
- When the workflow pauses, you'll see the form URL in the step output
- Open the form URL to submit your approval decision
- The workflow will automatically resume after form submission
GET /api/form/{runId}/{stepId}/{token}Returns the form fields and metadata.
POST /api/form/{runId}/{stepId}/{token}
Content-Type: application/json
{
"decision": "Approved",
"comments": "Looks good!",
"reviewer_name": "Jane Manager"
}Submits the form data and resumes workflow execution.
The workflow uses these field types (all supported by marktoflow):
| Type | Description | Example |
|---|---|---|
select |
Dropdown with predefined options | Approval decision (Approved/Rejected) |
text |
Multi-line text area | Reviewer comments |
string |
Single-line text input | Reviewer name |
number |
Numeric input | Amounts, quantities |
boolean |
Checkbox | Yes/no questions |
date |
Date picker | Deadlines, schedules |
email |
Email input with validation | Contact emails |
url |
URL input with validation | Reference links |
When a form is submitted, the data is injected into the workflow context as:
{stepId}_response
For this workflow, the approval step has output_variable: approval_response, so the form data is accessed via:
{{ approval_response_response.decision }}
{{ approval_response_response.comments }}
{{ approval_response_response.reviewer_name }}
When using the GUI:
- WebSocket connection provides real-time execution updates
- Form submission triggers immediate workflow resumption
- Step progress is displayed live in the UI
In production environments, consider:
- Authentication - Verify form submitter identity via tokens
- Expiration - Set timeouts for form submissions
- Notifications - Send emails/Slack messages with form links
- Validation - Add custom validation rules for form fields
- Audit Trail - Log all approval decisions with timestamps
examples/human-approval- Simple approval workflowexamples/multi-step-form- Complex multi-stage formsexamples/conditional-approval- Dynamic approval rules