Skip to main content

Getting Started with BankLingo Process Engine

This guide will walk you through creating, deploying, and executing your first BPMN process in the BankLingo Platform.

Prerequisites​

Before you begin, ensure you have:

  • BankLingo Platform installed and running
  • Access to the BankLingo API (base URL: https://your-instance.banklingo.com/api)
  • API credentials (API Key or OAuth token)
  • Basic understanding of BPMN 2.0 concepts
  • A REST client (Postman, cURL, or similar)

Step 1: Create Your First Process Definition​

Let's create a simple loan approval process with three steps:

  1. Submit application (automatic)
  2. Review application (user task)
  3. Notify applicant (automatic)

BPMN XML Definition​

Create a file named loan-approval.bpmn:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:custom="http://banklingo.com/schema/bpmn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
targetNamespace="http://banklingo.com/bpmn">

<bpmn:process id="LoanApproval_v1" name="Loan Approval Process" isExecutable="true">

<!-- Start Event -->
<bpmn:startEvent id="StartEvent_1" name="Application Received" />
<bpmn:sequenceFlow sourceRef="StartEvent_1" targetRef="Task_ValidateApplication" />

<!-- Script Task: Validate Application -->
<bpmn:scriptTask id="Task_ValidateApplication" name="Validate Application Data">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Script" value="
// Validate required fields
if (!loanAmount || loanAmount &lt;= 0) {
throw new Error('Invalid loan amount');
}
if (!customerName || customerName.trim() === '') {
throw new Error('Customer name is required');
}

// Calculate basic metrics
validationStatus = 'Passed';
validationDate = new Date().toISOString();

console.log('Application validated successfully');
" />
<custom:property name="ScriptLanguage" value="javascript" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:incoming>StartEvent_1</bpmn:incoming>
<bpmn:outgoing>Flow_ToReview</bpmn:outgoing>
</bpmn:scriptTask>
<bpmn:sequenceFlow id="Flow_ToReview" sourceRef="Task_ValidateApplication" targetRef="Task_ReviewApplication" />

<!-- User Task: Review Application -->
<bpmn:userTask id="Task_ReviewApplication" name="Review Loan Application">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="FormKey" value="loan-review-form" />
<custom:property name="UserActions" value="Approve,Reject,RequestMoreInfo" />
<custom:property name="EntityState" value="PendingReview" />
<custom:property name="ResponsibleTeams" value="LoanOfficers,CreditTeam" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:incoming>Flow_ToReview</bpmn:incoming>
<bpmn:outgoing>Flow_ToDecision</bpmn:outgoing>
</bpmn:userTask>
<bpmn:sequenceFlow id="Flow_ToDecision" sourceRef="Task_ReviewApplication" targetRef="Gateway_ApprovalDecision" />

<!-- Exclusive Gateway: Check Approval Decision -->
<bpmn:exclusiveGateway id="Gateway_ApprovalDecision" name="Approved?" default="Flow_Rejected">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
// Check the user action from the review task
if (userAction === 'Approve') {
return 'Flow_Approved';
} else if (userAction === 'Reject') {
return 'Flow_Rejected';
} else if (userAction === 'RequestMoreInfo') {
return 'Flow_MoreInfo';
}
return 'Flow_Rejected'; // Default to rejection
" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:incoming>Flow_ToDecision</bpmn:incoming>
<bpmn:outgoing>Flow_Approved</bpmn:outgoing>
<bpmn:outgoing>Flow_Rejected</bpmn:outgoing>
<bpmn:outgoing>Flow_MoreInfo</bpmn:outgoing>
</bpmn:exclusiveGateway>

<!-- Approved Path -->
<bpmn:sequenceFlow id="Flow_Approved" name="Approved" sourceRef="Gateway_ApprovalDecision" targetRef="Task_SendApprovalNotification" />

<bpmn:sendTask id="Task_SendApprovalNotification" name="Send Approval Notification">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Destination" value="/api/notifications/send" />
<custom:property name="Method" value="POST" />
<custom:property name="PayloadTemplate" value="{
&quot;recipientEmail&quot;: &quot;{{customerEmail}}&quot;,
&quot;subject&quot;: &quot;Loan Application Approved&quot;,
&quot;message&quot;: &quot;Your loan application for {{loanAmount}} has been approved!&quot;,
&quot;type&quot;: &quot;approval&quot;
}" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:incoming>Flow_Approved</bpmn:incoming>
<bpmn:outgoing>Flow_ToApprovedEnd</bpmn:outgoing>
</bpmn:sendTask>
<bpmn:sequenceFlow id="Flow_ToApprovedEnd" sourceRef="Task_SendApprovalNotification" targetRef="EndEvent_Approved" />
<bpmn:endEvent id="EndEvent_Approved" name="Application Approved" />

<!-- Rejected Path -->
<bpmn:sequenceFlow id="Flow_Rejected" name="Rejected" sourceRef="Gateway_ApprovalDecision" targetRef="Task_SendRejectionNotification" />

<bpmn:sendTask id="Task_SendRejectionNotification" name="Send Rejection Notification">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Destination" value="/api/notifications/send" />
<custom:property name="Method" value="POST" />
<custom:property name="PayloadTemplate" value="{
&quot;recipientEmail&quot;: &quot;{{customerEmail}}&quot;,
&quot;subject&quot;: &quot;Loan Application Rejected&quot;,
&quot;message&quot;: &quot;We regret to inform you that your loan application has been rejected.&quot;,
&quot;type&quot;: &quot;rejection&quot;
}" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:incoming>Flow_Rejected</bpmn:incoming>
<bpmn:outgoing>Flow_ToRejectedEnd</bpmn:outgoing>
</bpmn:sendTask>
<bpmn:sequenceFlow id="Flow_ToRejectedEnd" sourceRef="Task_SendRejectionNotification" targetRef="EndEvent_Rejected" />
<bpmn:endEvent id="EndEvent_Rejected" name="Application Rejected" />

<!-- More Info Path -->
<bpmn:sequenceFlow id="Flow_MoreInfo" name="More Info Needed" sourceRef="Gateway_ApprovalDecision" targetRef="Task_RequestMoreInfo" />

<bpmn:sendTask id="Task_RequestMoreInfo" name="Request Additional Information">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Destination" value="/api/notifications/send" />
<custom:property name="Method" value="POST" />
<custom:property name="PayloadTemplate" value="{
&quot;recipientEmail&quot;: &quot;{{customerEmail}}&quot;,
&quot;subject&quot;: &quot;Additional Information Required&quot;,
&quot;message&quot;: &quot;We need more information to process your loan application.&quot;,
&quot;type&quot;: &quot;info_request&quot;
}" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:incoming>Flow_MoreInfo</bpmn:incoming>
<bpmn:outgoing>Flow_ToMoreInfoEnd</bpmn:outgoing>
</bpmn:sendTask>
<bpmn:sequenceFlow id="Flow_ToMoreInfoEnd" sourceRef="Task_RequestMoreInfo" targetRef="EndEvent_MoreInfo" />
<bpmn:endEvent id="EndEvent_MoreInfo" name="More Info Requested" />

</bpmn:process>
</bpmn:definitions>

Step 2: Deploy the Process Definition​

Upload the BPMN file to the BankLingo Platform using the API.

API Request​

POST /api/process-definitions
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

{
"processKey": "LoanApproval_v1",
"name": "Loan Approval Process",
"description": "Simple loan approval workflow with review and notification",
"bpmnXml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>...",
"version": 1,
"isActive": true
}

Example using cURL​

curl -X POST https://your-instance.banklingo.com/api/process-definitions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d @- <<EOF
{
"processKey": "LoanApproval_v1",
"name": "Loan Approval Process",
"description": "Simple loan approval workflow",
"bpmnXml": "$(cat loan-approval.bpmn | jq -Rs .)",
"version": 1,
"isActive": true
}
EOF

Response​

{
"success": true,
"data": {
"processDefinitionId": "550e8400-e29b-41d4-a716-446655440000",
"processKey": "LoanApproval_v1",
"version": 1,
"deploymentTime": "2025-12-18T10:30:00Z",
"isActive": true,
"taskCount": 6
}
}

Step 3: Start a Process Instance​

Now that the process is deployed, start an instance with initial variables.

API Request​

POST /api/process-instances/start
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

{
"processKey": "LoanApproval_v1",
"businessKey": "LOAN-2025-001",
"variables": {
"loanAmount": 50000,
"customerName": "John Doe",
"customerEmail": "john.doe@example.com",
"loanPurpose": "Home Improvement",
"requestedTerm": 60
},
"executionMode": "Unsupervised"
}

Response​

{
"success": true,
"data": {
"instanceGuid": "660e8400-e29b-41d4-a716-446655440001",
"processKey": "LoanApproval_v1",
"businessKey": "LOAN-2025-001",
"status": "WaitingForUserAction",
"currentTaskId": "Task_ReviewApplication",
"currentTaskName": "Review Loan Application",
"startTime": "2025-12-18T10:35:00Z",
"variables": {
"loanAmount": 50000,
"customerName": "John Doe",
"customerEmail": "john.doe@example.com",
"loanPurpose": "Home Improvement",
"requestedTerm": 60,
"validationStatus": "Passed",
"validationDate": "2025-12-18T10:35:01Z"
}
}
}

What Happened?

  1. Process started at StartEvent_1
  2. Executed Task_ValidateApplication (ScriptTask) - validated data and set variables
  3. Reached Task_ReviewApplication (UserTask) - PAUSED waiting for user action

Step 4: Query Active User Tasks​

Find tasks that need human action.

API Request​

GET /api/user-tasks/active?assignedToTeam=LoanOfficers
Authorization: Bearer YOUR_API_TOKEN

Response​

{
"success": true,
"data": [
{
"taskId": "Task_ReviewApplication",
"taskName": "Review Loan Application",
"instanceGuid": "660e8400-e29b-41d4-a716-446655440001",
"processKey": "LoanApproval_v1",
"businessKey": "LOAN-2025-001",
"formKey": "loan-review-form",
"userActions": ["Approve", "Reject", "RequestMoreInfo"],
"responsibleTeams": ["LoanOfficers", "CreditTeam"],
"entityState": "PendingReview",
"createdAt": "2025-12-18T10:35:01Z",
"variables": {
"loanAmount": 50000,
"customerName": "John Doe",
"customerEmail": "john.doe@example.com",
"validationStatus": "Passed"
}
}
],
"totalCount": 1
}

Step 5: Complete the User Task​

A loan officer reviews the application and approves it.

API Request​

POST /api/user-tasks/complete
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

{
"instanceGuid": "660e8400-e29b-41d4-a716-446655440001",
"taskId": "Task_ReviewApplication",
"userAction": "Approve",
"variables": {
"reviewerName": "Jane Smith",
"reviewerComments": "Strong application. Approved for full amount.",
"approvalDate": "2025-12-18T11:00:00Z"
}
}

Response​

{
"success": true,
"data": {
"instanceGuid": "660e8400-e29b-41d4-a716-446655440001",
"status": "Completed",
"completedAt": "2025-12-18T11:00:05Z",
"executionPath": [
"StartEvent_1",
"Task_ValidateApplication",
"Task_ReviewApplication",
"Gateway_ApprovalDecision",
"Task_SendApprovalNotification",
"EndEvent_Approved"
]
}
}

What Happened?

  1. User task completed with action "Approve"
  2. Gateway evaluated condition → returned "Flow_Approved"
  3. Task_SendApprovalNotification executed → sent email via API
  4. Process reached EndEvent_Approved → COMPLETED

Step 6: Check Process Instance Status​

View the final state of the process.

API Request​

GET /api/process-instances/660e8400-e29b-41d4-a716-446655440001
Authorization: Bearer YOUR_API_TOKEN

Response​

{
"success": true,
"data": {
"instanceGuid": "660e8400-e29b-41d4-a716-446655440001",
"processKey": "LoanApproval_v1",
"businessKey": "LOAN-2025-001",
"status": "Completed",
"startTime": "2025-12-18T10:35:00Z",
"endTime": "2025-12-18T11:00:05Z",
"duration": "00:25:05",
"currentTaskId": null,
"executionMode": "Unsupervised",
"variables": {
"loanAmount": 50000,
"customerName": "John Doe",
"customerEmail": "john.doe@example.com",
"loanPurpose": "Home Improvement",
"requestedTerm": 60,
"validationStatus": "Passed",
"validationDate": "2025-12-18T10:35:01Z",
"userAction": "Approve",
"reviewerName": "Jane Smith",
"reviewerComments": "Strong application. Approved for full amount.",
"approvalDate": "2025-12-18T11:00:00Z"
},
"executionHistory": [
{
"taskId": "StartEvent_1",
"taskName": "Application Received",
"taskType": "StartEvent",
"executedAt": "2025-12-18T10:35:00Z",
"status": "Completed"
},
{
"taskId": "Task_ValidateApplication",
"taskName": "Validate Application Data",
"taskType": "ScriptTask",
"executedAt": "2025-12-18T10:35:01Z",
"duration": "00:00:01",
"status": "Completed"
},
{
"taskId": "Task_ReviewApplication",
"taskName": "Review Loan Application",
"taskType": "UserTask",
"executedAt": "2025-12-18T10:35:01Z",
"completedAt": "2025-12-18T11:00:00Z",
"duration": "00:24:59",
"completedBy": "jane.smith@bank.com",
"userAction": "Approve",
"status": "Completed"
},
{
"taskId": "Gateway_ApprovalDecision",
"taskName": "Approved?",
"taskType": "ExclusiveGateway",
"executedAt": "2025-12-18T11:00:00Z",
"takenPath": "Flow_Approved",
"status": "Completed"
},
{
"taskId": "Task_SendApprovalNotification",
"taskName": "Send Approval Notification",
"taskType": "SendTask",
"executedAt": "2025-12-18T11:00:01Z",
"duration": "00:00:04",
"status": "Completed"
},
{
"taskId": "EndEvent_Approved",
"taskName": "Application Approved",
"taskType": "EndEvent",
"executedAt": "2025-12-18T11:00:05Z",
"status": "Completed"
}
]
}
}

Summary​

Congratulations! You've successfully:

✅ Created a BPMN process definition with multiple task types
✅ Deployed the process to BankLingo Platform
✅ Started a process instance with initial variables
✅ Queried active user tasks
✅ Completed a user task with action and variables
✅ Viewed the complete execution history

Next Steps​

Now that you understand the basics, explore more advanced features:

Common Next Actions​

Test with Supervised Mode​

Start a process in supervised mode to step through execution:

{
"processKey": "LoanApproval_v1",
"businessKey": "LOAN-2025-002",
"variables": {...},
"executionMode": "Supervised"
}

Then use:

  • POST /api/process-instances/{guid}/step-forward - Execute next task
  • POST /api/process-instances/{guid}/step-backward - Move pointer back

Add More Task Types​

Enhance your process with:

  • ServiceTask - Call external REST APIs
  • BusinessRuleTask - Execute decision tables
  • CallActivity - Invoke sub-processes

Monitor Processes​

Use the monitoring endpoints:

  • GET /api/process-instances/active - All running instances
  • GET /api/process-instances/by-status/{status} - Filter by status
  • GET /api/process-instances/by-business-key/{key} - Find specific instances

Questions? Check the FAQ or refer to the API Reference.