Application Lifecycle

Complete guide to loan application lifecycle from submission to decision, including status transitions and available actions

Application Lifecycle

📘

Complete Application Journey

Understand how loan applications flow through the Loan Origination System from initial submission through final decision and onboarding to the Loan Management System.

The Loan Origination System (LOS) manages the complete lifecycle of loan applications, from the moment a borrower submits an application through final approval or rejection. This guide covers all application statuses, transitions, available actions, and how to integrate with the application workflow via API.


Application Lifecycle Overview

The application lifecycle follows a structured workflow designed to ensure thorough review and verification before making a lending decision. Applications progress through defined statuses, with specific actions available at each stage.

End-to-End Flow

%%{init: {'theme': 'base', 'themeVariables': {'background': '#ffffff', 'mainBkg': '#ffffff', 'clusterBkg': '#ffffff', 'clusterBorder': '#2563eb', 'titleColor': '#000000', 'primaryColor': '#2563eb', 'primaryTextColor': '#ffffff', 'lineColor': '#374151'}, 'flowchart': {'padding': 15, 'nodeSpacing': 25, 'rankSpacing': 30}}}%%
flowchart LR
    subgraph MainContainer[📋 Application Lifecycle]
        direction LR
        A[📝 Submit] --> B[📄 Docs]
        B --> C[🔍 Review]
        C --> D{⚖️ Decide}
        D -->|✅| E[✅ Approved]
        D -->|❌| F[❌ Rejected]
        E --> G[🚀 LMS]
    end
    
    style A fill:#2563eb,stroke:#1e40af,color:#fff
    style B fill:#2563eb,stroke:#1e40af,color:#fff
    style C fill:#2563eb,stroke:#1e40af,color:#fff
    style D fill:#6b7280,stroke:#4b5563,color:#fff
    style E fill:#059669,stroke:#047857,color:#fff
    style F fill:#dc2626,stroke:#b91c1c,color:#fff
    style G fill:#1e40af,stroke:#1e3a8a,color:#fff

Application Statuses

Applications progress through a series of statuses that reflect their current stage in the review process. Each status enables specific actions and determines what operations can be performed.

StatusDescriptionNext Actions
SubmittedInitial submission receivedReview, Request Docs, Claim
Pending ApprovalUnder review by back officeApprove, Reject, Request More Info
Offer GeneratedLoan offer createdAccept Offer, Reject Offer
Pending OfferAwaiting borrower acceptance- (Borrower action required)
ApprovedApplication approvedOnboard to LMS, Generate Documents
RejectedApplication rejected- (Terminal status)
Not InterestedBorrower declined offer- (Terminal status)

Status Flow Diagram

%%{init: {'theme': 'base', 'themeVariables': {'background': '#ffffff', 'mainBkg': '#ffffff', 'clusterBkg': '#ffffff', 'clusterBorder': '#2563eb', 'titleColor': '#000000', 'primaryColor': '#2563eb', 'primaryTextColor': '#ffffff', 'lineColor': '#374151'}, 'flowchart': {'padding': 15, 'nodeSpacing': 20, 'rankSpacing': 25}}}%%
flowchart LR
    subgraph MainContainer[🔄 Status Transitions]
        direction LR
        A[📝 Submitted] --> B[📋 Pending Approval]
        B --> C[💼 Offer Generated]
        C --> D[⏳ Pending Offer]
        D --> E[✅ Approved]
        B --> F[❌ Rejected]
        D --> G[🚫 Not Interested]
        E --> H[🚀 Onboard LMS]
    end
    
    style A fill:#2563eb,stroke:#1e40af,color:#fff
    style B fill:#d97706,stroke:#b45309,color:#fff
    style C fill:#2563eb,stroke:#1e40af,color:#fff
    style D fill:#d97706,stroke:#b45309,color:#fff
    style E fill:#059669,stroke:#047857,color:#fff
    style F fill:#dc2626,stroke:#b91c1c,color:#fff
    style G fill:#dc2626,stroke:#b91c1c,color:#fff
    style H fill:#1e40af,stroke:#1e3a8a,color:#fff

Available Actions

At each stage of the application lifecycle, specific actions are available to manage and process the application. These actions are accessible via API endpoints.

ActionDescriptionAPI EndpointAvailable Statuses
Edit ApplicationUpdate borrower detailsPUT /applications/{id}All statuses
ApproveApprove applicationPOST /applications/{id}/approvePending Approval
RejectReject with reasonPOST /applications/{id}/rejectPending Approval
ClaimAssign to selfPOST /applications/{id}/claimSubmitted, Pending Approval
ReleaseUnassign applicationPOST /applications/{id}/releaseAny assigned status
AssignAssign to another userPOST /applications/{id}/assignSubmitted, Pending Approval
EscalateCreate escalation taskPOST /escalationsAny status
Add NoteAdd internal notePOST /applications/{id}/notesAll statuses
Do Not ContactFlag as DNCPUT /applications/{id}/doNotContactAll statuses

Application Tabs and Sections

Each application contains multiple sections accessible via API endpoints. These sections provide detailed information about different aspects of the application.

TabData AvailableAPI Endpoint
Borrower InformationPersonal details, contact infoGET /applications/{id}/borrower
Owners/OfficersBusiness owners, officersGET /applications/{id}/owners
Funding InfoBank account detailsGET /applications/{id}/funding
3rd Party DataCredit reports, external dataGET /applications/{id}/thirdParty
OffersLoan offers generatedGET /applications/{id}/offers
DocumentsUploaded documentsGET /applications/{id}/documents
NotesInternal notes and commentsGET /applications/{id}/notes
Status HistoryComplete audit trailGET /applications/{id}/statusHistory

API Operations

Get Application Details

Retrieve complete application information including current status, borrower details, and all associated data.

curl -X GET 'https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/APP-2024-001234' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json'
const getApplication = async (applicationId) => {
  const response = await fetch(
    `https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/${applicationId}`,
    {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json'
      }
    }
  );
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  return await response.json();
};
import requests

def get_application(application_id):
    url = f"https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/{application_id}"
    headers = {
        "Authorization": "Bearer YOUR_TOKEN",
        "Content-Type": "application/json"
    }
    
    response = requests.get(url, headers=headers)
    response.raise_for_status()
    return response.json()
public String getApplication(String applicationId) throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/" + applicationId))
        .header("Authorization", "Bearer YOUR_TOKEN")
        .header("Content-Type", "application/json")
        .GET()
        .build();
    
    HttpResponse<String> response = client.send(request,
        HttpResponse.BodyHandlers.ofString());
    return response.body();
}

Approve Application

Approve an application that is pending approval. This action moves the application to the Approved status.

curl -X POST 'https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/APP-2024-001234/approve' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "approvalNotes": "All verifications passed",
    "approvedAmount": 25000
  }'
const approveApplication = async (applicationId, approvalData) => {
  const response = await fetch(
    `https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/${applicationId}/approve`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(approvalData)
    }
  );
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  return await response.json();
};

// Usage
await approveApplication('APP-2024-001234', {
  approvalNotes: 'All verifications passed',
  approvedAmount: 25000
});
import requests

def approve_application(application_id, approval_data):
    url = f"https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/{application_id}/approve"
    headers = {
        "Authorization": "Bearer YOUR_TOKEN",
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, json=approval_data, headers=headers)
    response.raise_for_status()
    return response.json()

# Usage
approve_application('APP-2024-001234', {
    'approvalNotes': 'All verifications passed',
    'approvedAmount': 25000
})
public String approveApplication(String applicationId, String requestBody) throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/" + applicationId + "/approve"))
        .header("Authorization", "Bearer YOUR_TOKEN")
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(requestBody))
        .build();
    
    HttpResponse<String> response = client.send(request,
        HttpResponse.BodyHandlers.ofString());
    return response.body();
}

Reject Application

Reject an application with a reason code. This action moves the application to the Rejected status (terminal).

curl -X POST 'https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/APP-2024-001234/reject' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "rejectionReason": "Insufficient income documentation",
    "rejectionCode": "INCOME_01"
  }'
const rejectApplication = async (applicationId, rejectionData) => {
  const response = await fetch(
    `https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/${applicationId}/reject`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(rejectionData)
    }
  );
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  return await response.json();
};

// Usage
await rejectApplication('APP-2024-001234', {
  rejectionReason: 'Insufficient income documentation',
  rejectionCode: 'INCOME_01'
});
import requests

def reject_application(application_id, rejection_data):
    url = f"https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/{application_id}/reject"
    headers = {
        "Authorization": "Bearer YOUR_TOKEN",
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, json=rejection_data, headers=headers)
    response.raise_for_status()
    return response.json()

# Usage
reject_application('APP-2024-001234', {
    'rejectionReason': 'Insufficient income documentation',
    'rejectionCode': 'INCOME_01'
})
public String rejectApplication(String applicationId, String requestBody) throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/" + applicationId + "/reject"))
        .header("Authorization", "Bearer YOUR_TOKEN")
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(requestBody))
        .build();
    
    HttpResponse<String> response = client.send(request,
        HttpResponse.BodyHandlers.ofString());
    return response.body();
}

Claim Application

Assign an application to yourself for review. This action is available for applications in Submitted or Pending Approval status.

curl -X POST 'https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/APP-2024-001234/claim' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json'
const claimApplication = async (applicationId) => {
  const response = await fetch(
    `https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/${applicationId}/claim`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json'
      }
    }
  );
  
  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }
  
  return await response.json();
};
import requests

def claim_application(application_id):
    url = f"https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/{application_id}/claim"
    headers = {
        "Authorization": "Bearer YOUR_TOKEN",
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers)
    response.raise_for_status()
    return response.json()
public String claimApplication(String applicationId) throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://loc.demo.kendra.lendfoundry.com/v1/darbaan/back-office/rest/api/applications/" + applicationId + "/claim"))
        .header("Authorization", "Bearer YOUR_TOKEN")
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.noBody())
        .build();
    
    HttpResponse<String> response = client.send(request,
        HttpResponse.BodyHandlers.ofString());
    return response.body();
}

Onboarding to LMS

When an application reaches the Approved status, it can be onboarded to the Loan Management System (LMS) for servicing. The application number serves as the linking key between LOS and LMS.

📘

Seamless Integration

Approved applications automatically transfer to LMS where they become active loans. The application number (APP-YYYY-NNNNNN) links the origination record to the loan record in LMS.

Onboarding Process

  1. Application Approved - Application reaches Approved status in LOS
  2. Data Transfer - Application data transfers to LMS via API
  3. Loan Creation - Loan record created in LMS with loan number (LN-YYYY-NNNNNN)
  4. Active Servicing - Loan becomes active and ready for payment processing

For detailed information about onboarding approved loans to LMS, see the Loan Onboarding Guide.


Screenshots

📷

Screenshot: Application Details View

The application details page shows all information about a loan application, including borrower information, status, documents, and available actions.

Application View

Next Steps

ResourceDescription
Document VerificationLearn about verification workflows
Loan OnboardingOnboard approved applications to LMS
API ReferenceComplete API endpoint documentation

Ready to Continue?

Learn about Document Verification to understand how applications are verified before approval.