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_ApprovedCOMPLETED

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.