BPMCore Comments API
The Comments API enables adding and retrieving comments/notes for various banking entities. Comments provide an audit trail of interactions, decisions, and observations related to clients, loans, deposits, and insurance policies.
Base Endpoint
POST /api/core/cmd
Quick Navigation
- Retrieve Comments List - Query comments with filters
- Add Comment (Unified) - ⭐ NEW Unified comment creation
- Integration Notes - Implementation guidance
- Best Practices - Comment quality guidelines
- Security & Compliance - Access control and privacy
Commands & Queries
1. Retrieve Comments List (All Entities)
Retrieves a paginated list of comments across all entity types or filtered by specific entity.
Command Name: RetrieveCommentsListQuery
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
entity | string | Yes | Entity type: "Client", "Loan", "Deposit", "Policy", or "All" |
entityId | long | No | Filter by specific entity ID (required if entity != "All") |
startDate | string | No | Filter by comment date start (YYYY-MM-DD) |
endDate | string | No | Filter by comment date end (YYYY-MM-DD) |
searchText | string | No | Search in comment text |
userId | long | No | Filter by user who added comment |
pageNumber | integer | No | Page number (default: 1) |
pageSize | integer | No | Items per page (default: 20) |
isExport | boolean | No | Export all results (default: false) |
Request Example
{
"Cmd": "RetrieveCommentsListQuery",
"Data": {
"entity": "Client",
"entityId": 12345,
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"pageNumber": 1,
"pageSize": 50
}
}
Response Structure
{
"IsSuccessful": true,
"StatusCode": "00",
"Message": "Comments retrieved successfully.",
"Data": {
"items": [
{
"Id": 1001,
"EntityType": "Client",
"EntityId": 12345,
"EntityReference": "CL-000123",
"CommentText": "Customer expressed interest in savings products during phone call.",
"UserId": 101,
"UserName": "Jane Doe",
"UserEmail": "jane.doe@banklingo.com",
"CommentDate": "2024-01-15T10:30:00",
"IsInternal": false,
"CreatedAt": "2024-01-15T10:30:00",
"UpdatedAt": "2024-01-15T10:30:00"
},
{
"Id": 1002,
"EntityType": "Client",
"EntityId": 12345,
"EntityReference": "CL-000123",
"CommentText": "Approved KYC documentation verified.",
"UserId": 102,
"UserName": "John Smith",
"UserEmail": "john.smith@banklingo.com",
"CommentDate": "2024-01-16T14:20:00",
"IsInternal": true,
"CreatedAt": "2024-01-16T14:20:00",
"UpdatedAt": "2024-01-16T14:20:00"
}
],
"totalRows": 25,
"totalPages": 1,
"pageSize": 50,
"currentPage": 1
},
"HasNext": false,
"HasPrevious": false
}
Response Fields
| Field | Type | Description |
|---|---|---|
Id | long | Comment ID |
EntityType | string | Type of entity (Client, Loan, Deposit, Policy) |
EntityId | long | ID of the associated entity |
EntityReference | string | Human-readable reference (account number, client code) |
CommentText | string | The comment content |
UserId | long | User who added the comment |
UserName | string | Full name of the user |
UserEmail | string | Email of the user |
CommentDate | datetime | When the comment was added |
IsInternal | boolean | True if internal note (not visible to customer) |
CreatedAt | datetime | Record creation timestamp |
UpdatedAt | datetime | Last update timestamp |
2. Retrieve Client Comments
Retrieves all comments for a specific client.
Command Name: RetrieveClientCommentListQuery
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
clientId | long | Yes | Client ID |
startDate | string | No | Filter by comment date start |
endDate | string | No | Filter by comment date end |
searchText | string | No | Search in comment text |
pageNumber | integer | No | Page number (default: 1) |
pageSize | integer | No | Items per page (default: 20) |
isExport | boolean | No | Export all results (default: false) |
Request Example
{
"Cmd": "RetrieveClientCommentListQuery",
"Data": {
"clientId": 12345,
"pageNumber": 1,
"pageSize": 20
}
}
Response Structure
Same as RetrieveCommentsListQuery, filtered to the specified client.
3. Retrieve Loan Comments
Retrieves all comments for a specific loan account.
Command Name: RetrieveLoanCommentListQuery
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
loanId | long | Yes | Loan account ID |
startDate | string | No | Filter by comment date start |
endDate | string | No | Filter by comment date end |
searchText | string | No | Search in comment text |
pageNumber | integer | No | Page number (default: 1) |
pageSize | integer | No | Items per page (default: 20) |
isExport | boolean | No | Export all results (default: false) |
Request Example
{
"Cmd": "RetrieveLoanCommentListQuery",
"Data": {
"loanId": 67890,
"pageNumber": 1,
"pageSize": 20
}
}
Typical Loan Comments
- Loan application notes
- Credit assessment observations
- Approval/rejection reasons
- Disbursement authorization notes
- Collection follow-up notes
- Restructuring discussions
- Payment plan negotiations
4. Retrieve Deposit Comments
Retrieves all comments for a specific deposit account.
Command Name: RetrieveDepositCommentListQuery
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
depositId | long | Yes | Deposit account ID |
startDate | string | No | Filter by comment date start |
endDate | string | No | Filter by comment date end |
searchText | string | No | Search in comment text |
pageNumber | integer | No | Page number (default: 1) |
pageSize | integer | No | Items per page (default: 20) |
isExport | boolean | No | Export all results (default: false) |
Request Example
{
"Cmd": "RetrieveDepositCommentListQuery",
"Data": {
"depositId": 54321,
"pageNumber": 1,
"pageSize": 20
}
}
Typical Deposit Comments
- Account opening notes
- Service request details
- Account closure discussions
- Statement request notes
- Balance inquiry interactions
- Dormancy status updates
5. Retrieve Policy Comments
Retrieves all comments for a specific insurance policy.
Command Name: RetrievePolicyCommentListQuery
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
policyId | long | Yes | Insurance policy ID |
startDate | string | No | Filter by comment date start |
endDate | string | No | Filter by comment date end |
searchText | string | No | Search in comment text |
pageNumber | integer | No | Page number (default: 1) |
pageSize | integer | No | Items per page (default: 20) |
isExport | boolean | No | Export all results (default: false) |
Request Example
{
"Cmd": "RetrievePolicyCommentListQuery",
"Data": {
"policyId": 99887,
"pageNumber": 1,
"pageSize": 20
}
}
Typical Policy Comments
- Policy issuance notes
- Premium payment reminders
- Claims processing updates
- Beneficiary change requests
- Policy renewal discussions
- Lapse notifications
Comment Types
Internal vs External Comments
- Internal Comments (
IsInternal: true): Visible only to bank staff, used for internal notes, decisions, and observations - External Comments (
IsInternal: false): May be shared with customers or appear in customer-facing systems
Usage Scenarios
| Scenario | Entity Type | Example Comment |
|---|---|---|
| KYC Review | Client | "National ID verified and matches BVN record" |
| Credit Decision | Loan | "Approved subject to 10% down payment" |
| Collection | Loan | "Customer promised payment by Friday" |
| Account Dormancy | Deposit | "Account flagged for dormancy - no activity for 12 months" |
| Claims Processing | Policy | "Claim approved - awaiting payment authorization" |
Common Use Cases
Example 1: Client Interaction Log
Add comments during customer service interactions:
{
"Cmd": "RetrieveClientCommentListQuery",
"Data": {
"clientId": 12345,
"startDate": "2024-01-01",
"endDate": "2024-01-31"
}
}
Example 2: Loan Collection Follow-up
Retrieve collection notes for loan accounts:
{
"Cmd": "RetrieveLoanCommentListQuery",
"Data": {
"loanId": 67890,
"searchText": "collection",
"pageNumber": 1,
"pageSize": 50
}
}
Example 3: Policy Claims Audit Trail
Get all comments related to a policy claim:
{
"Cmd": "RetrievePolicyCommentListQuery",
"Data": {
"policyId": 99887,
"startDate": "2024-01-01",
"isExport": true
}
}
Example 4: User Activity Report
Find all comments by a specific user:
{
"Cmd": "RetrieveCommentsListQuery",
"Data": {
"entity": "All",
"userId": 101,
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"isExport": true
}
}
Integration Notes
Adding Comments
The BPMCore Comments API now supports unified comment creation through the AddCommentCommand:
{
"Cmd": "AddCommentCommand",
"Data": {
"entity": "Loan",
"entityId": 12345,
"comment": "Loan disbursement completed successfully."
}
}
Alternative methods:
- Entity-specific commands (e.g.,
CreateClientCommentCommand) - Legacy, use AddCommentCommand instead - Workflow automation (automatic comments from process engine)
- UI-driven comment forms
Commands & Queries
2. Add Comment (Unified Command) ⭐ NEW
Add a comment to any entity (Client, Loan, Deposit, or Policy) using a single unified command.
Command Name: AddCommentCommand
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
entity | string | Yes | Entity type: "Client", "Loan", "Deposit", or "Policy" |
entityId | long | No* | Entity database ID |
encodedKey | string | No* | Entity encoded key or account number |
comment | string | Yes | Comment text (max length varies by entity) |
* Either entityId or encodedKey must be provided.
Request Example - Using Entity ID
{
"Cmd": "AddCommentCommand",
"Data": {
"entity": "Loan",
"entityId": 12345,
"comment": "Loan application approved by credit committee. Disbursement scheduled for 2025-12-30."
}
}
Request Example - Using Encoded Key
{
"Cmd": "AddCommentCommand",
"Data": {
"entity": "Client",
"encodedKey": "CLIENT-12345",
"comment": "Customer called to inquire about savings account interest rates."
}
}
Response Structure
{
"IsSuccessful": true,
"StatusCode": "00",
"Message": "Comment added successfully.",
"Data": {
"commentId": 5001,
"loanId": 12345,
"loanEncodedKey": "LOAN-67890",
"accountNumber": "ACC-001-12345",
"timestamp": "2025-12-24T15:30:00Z"
}
}
Response Fields by Entity
Client Comments:
{
"commentId": 5001,
"clientId": 12345,
"clientEncodedKey": "CLIENT-67890",
"timestamp": "2025-12-24T15:30:00Z"
}
Loan Comments:
{
"commentId": 5002,
"loanId": 12345,
"loanEncodedKey": "LOAN-67890",
"accountNumber": "ACC-001-12345",
"timestamp": "2025-12-24T15:30:00Z"
}
Deposit Comments:
{
"commentId": 5003,
"depositId": 12345,
"depositEncodedKey": "DEP-67890",
"accountNumber": "DEP-001-12345",
"timestamp": "2025-12-24T15:30:00Z"
}
Policy Comments:
{
"commentId": 5004,
"policyId": 12345,
"policyEncodedKey": "POL-67890",
"policyNumber": "INS-001-12345",
"timestamp": "2025-12-24T15:30:00Z"
}
Error Responses
Missing Entity Type:
{
"IsSuccessful": false,
"StatusCode": "96",
"Message": "Entity type is required."
}
Missing Comment Text:
{
"IsSuccessful": false,
"StatusCode": "96",
"Message": "Comment text is required."
}
Invalid Entity Type:
{
"IsSuccessful": false,
"StatusCode": "96",
"Message": "Invalid entity specified. Valid values are: Client, Loan, Deposit, Policy."
}
Entity Not Found:
{
"IsSuccessful": false,
"StatusCode": "96",
"Message": "Loan account not found."
}
Missing Identifier:
{
"IsSuccessful": false,
"StatusCode": "96",
"Message": "Either entityId or encodedKey is required."
}
C# Usage Example
var command = new AddCommentCommand
{
Data = new
{
entity = "Loan",
entityId = 12345,
comment = "Loan approved and disbursed."
}
};
var response = await _mediator.Send(command);
if (response.IsSuccessful)
{
var commentId = response.Data.commentId;
Console.WriteLine($"Comment added with ID: {commentId}");
}
JavaScript/TypeScript Example
interface AddCommentRequest {
entity: 'Client' | 'Loan' | 'Deposit' | 'Policy';
entityId?: number;
encodedKey?: string;
comment: string;
}
async function addComment(request: AddCommentRequest) {
const response = await axios.post('/api/core/cmd', {
Cmd: 'AddCommentCommand',
Data: request
});
if (response.data.IsSuccessful) {
console.log('Comment added:', response.data.Data.commentId);
} else {
console.error('Error:', response.data.Message);
}
return response.data;
}
// Usage - Add loan comment by ID
await addComment({
entity: 'Loan',
entityId: 12345,
comment: 'Disbursement completed successfully.'
});
// Usage - Add client comment by encoded key
await addComment({
entity: 'Client',
encodedKey: 'CLIENT-12345',
comment: 'Customer requested account statement.'
});
Best Practices
- Use entityId when available: More efficient than encoded key lookup
- Provide meaningful comments: Include context, decisions, and actions taken
- Include relevant details: Reference numbers, amounts, dates when applicable
- Standardize format: Use consistent formatting for similar comment types
- Error handling: Always check
IsSuccessfulbefore processing response
Validation Rules
- Entity: Must be one of: "Client", "Loan", "Deposit", "Policy" (case-sensitive)
- EntityId or EncodedKey: At least one must be provided
- Comment: Required, cannot be empty or whitespace only
- Comment Length: Typically limited to 1000-5000 characters (varies by entity)
Use Cases
Loan Processing:
{
"entity": "Loan",
"entityId": 12345,
"comment": "Credit committee approved loan of ₦5,000,000 at 12% interest rate for 24 months. Collateral: Property at 123 Main St valued at ₦8,000,000."
}
Customer Service:
{
"entity": "Client",
"encodedKey": "CLIENT-67890",
"comment": "Customer called regarding unauthorized transaction on 2025-12-20. Case escalated to fraud department. Ref: FRAUD-2025-001."
}
Deposit Management:
{
"entity": "Deposit",
"entityId": 54321,
"comment": "Fixed deposit matured on 2025-12-24. Principal ₦1,000,000 + Interest ₦120,000 = Total ₦1,120,000. Customer opted for renewal at 11% for 12 months."
}
Insurance Policy:
{
"entity": "Policy",
"encodedKey": "POL-99999",
"comment": "Premium payment of ₦50,000 received via bank transfer. Policy now active until 2026-12-24. Beneficiary updated to spouse per customer request."
}
Comment Timestamps
CommentDate: When the comment was logically made (user-specified or defaults to current time)CreatedAt: Database record creation timestampUpdatedAt: Last modification timestamp (if comments are editable)
Search Functionality
The searchText parameter performs case-insensitive searches across:
- Comment text content
- User names
- Entity references
Audit Trail
Comments provide a complete audit trail:
- Who made the comment (UserId, UserName)
- When it was made (CommentDate)
- What entity it relates to (EntityType, EntityId)
- The actual comment text
Best Practices
- Detailed Comments: Encourage staff to add detailed, meaningful comments
- Consistent Formatting: Use standardized formats for specific comment types
- Internal Flag Usage: Mark sensitive information as internal
- Regular Reviews: Periodically review comments for compliance and quality
- Search Optimization: Use date filters to narrow searches for better performance
- Export for Reporting: Use
isExport: truefor comprehensive audit reports
Comment Best Practices by Entity
Client Comments
✅ Good: "Customer requested information about fixed deposit rates. Sent product brochure via email."
❌ Bad: "Called customer."
Loan Comments
✅ Good: "Loan application approved. Credit score: 750. DTI ratio: 35%. Collateral: Property valued at ₦50M."
❌ Bad: "Approved."
Deposit Comments
✅ Good: "Account dormant since 2023-06-15. Sent reactivation letter via registered mail on 2024-01-10."
❌ Bad: "Account dormant."
Policy Comments
✅ Good: "Premium payment of ₦25,000 received on 2024-01-15. Policy active until 2025-01-15."
❌ Bad: "Payment received."
Security & Compliance
Access Control
- Users can only view comments for entities they have permission to access
- Internal comments are restricted to authorized staff
- External comments may be visible to customers (system configuration)
Data Privacy
- Comments may contain personal or sensitive information
- Ensure compliance with data protection regulations
- Regular audits of comment content for PII/sensitive data
Retention
- Comments are typically retained indefinitely for audit purposes
- May be subject to data retention policies
- Soft-delete mechanisms may apply
Related APIs
Documentation Author: Owa Oluwasegun Tunbosun, Senior Platform Engineer