CoreWave API Channel Execution Guide (Operator Grade)
Version: v1
Date: 2026-05-31
Purpose: This is the fastest possible operational guide.
If you only have 10 seconds, use section 1.
Export API Reference (.json) for Postman
1. 10-Second Cheat Sheet
1.1 Do-This Mapping
| You Want To Do | Call This Endpoint First | Then | Notes |
|---|---|---|---|
| Get access token | POST /api/auth/v1/authenticate | Use token for all calls | Required first step |
| Create customer + account | POST /api/account/v1/createcustomeraccount | GET /api/account/v1/getbyaccountnumber | Supports documents |
| Create account only | POST /api/account/v1/createaccount | GET /api/account/v1/getbyaccountnumber | Existing customer required |
| Create virtual account | POST /api/account/v1/createvirtualaccount | GET /api/account/v1/getbyaccountnumber | Corporate collection alias for NIP/NPS funding only |
| Update account | PUT /api/account/v1/updatecustomeraccount | GET /api/account/v1/getbyaccountnumber | Virtual-account IDs are rejected; update settlement account |
| Search accounts | GET /api/account/v1/searchaccount | - | Any filter subset |
| Add agent | POST /api/agent/v1/add | GET /api/agent/v1/search | Agent is separate from account officer |
| Balance inquiry | GET /api/account/v1/getaccountbalancebyaccountnumber | Optional extended balance | |
| Close account | POST /api/postings/v1/closeaccount | Verify by search | Balance must be zero |
| Local transfer (internal) | POST /api/transfer/v1/localfundtransfer | GET /api/transfer/v1/tsq/local | Account/GL combos allowed |
| Outward transfer | POST /api/transfer/v1/outwardtransfer | GET /api/transfer/v1/tsq | TSQ decides final state |
| Bills payment | POST /api/bills/v1/vend | POST /api/bills/v1/tsq | Reversal handled on failure |
| Get electricity token | GET /api/bills/v1/gettoken | - | By posting/payment ref |
| List cards | GET /api/card/v1/searchcards | - | |
| Add card to account | POST /api/card/v1/addcardtoaccount | Provider ops | Issuance charge may post |
| Block/Unblock Providus card | PUT /api/card/v1/providus/blockunblockcard | - | status 1/2 |
| Update Interswitch channel access | PUT /api/card/v1/interswitch/updatecardchannelaccess | - | atm/pos/web flags |
| Add loan | POST /api/loanaccount/v1/add | Credit bureau review, AI review, approval, then disbursement | linkedNumber must match owner; agentCode is optional |
| Loan bureau review | GET /api/loanaccount/v1/loancreditbureau | GET /api/loanaccount/v1/loanaireview | requires loanAccountNumber; run before approval when enabled |
| Loan certificate / offer letter | GET /api/loanaccount/v1/view-certificate/{ID} | - | use loan id from search; returns Base64 PDF data URL |
| Add group loan | POST /api/loanaccount/v1/addgrouploan | POST /api/loanaccount/v1/disbursegrouploan | uses group loan product + participant loan requests |
| Repay loan | POST /api/loanaccount/v1/repayloan | - | collectionsGL required |
| Repay group loan | POST /api/loanaccount/v1/repaygrouploan | GET /api/loanaccount/v1/searchgrouploan | participant-level repayment payload |
| Group loan bureau review | GET /api/loanaccount/v1/grouploancreditbureau | GET /api/loanaccount/v1/grouploanaireview | requires groupLoanID |
| Add fixed deposit | POST /api/fixeddepositaccount/v1/add | topup/update/liquidate | |
| Fixed deposit certificate | GET /api/fixeddepositaccount/v1/view-certificate/{ID}/{type} | - | use fixed deposit id from search; type is PDF or Excel |
| Place lien | POST /api/accountlien/v1/placelien | update/unplace | |
| Set account transfer limit | PUT /api/limit/v1/addupdateaccountlimit | GET /api/limit/v1/getaccountlimit | transfer limits only |
| Upload customer/account doc | POST /api/operations/v1/uploaddocument | optional delete | base64url, max 10MB |
| Add or update record extra data | PUT /api/entity-additional-metadata/v1/{entityType}/{entityId} | Fetch with GET first when merging keys | JSON object or array, max 64 KB |
| Send SMS / Email | POST /api/operations/v1/sendsms / sendemail | - | |
| Get statement/report | GET /api/report/v1/... | export/receipt |
1.2 Mandatory Request Headers
Authorization: Bearer {token}request-reference: {unique-string}Content-Type: application/json
1.3 Critical Global Rules
- Authenticate first.
- Amounts are Naira.
- API keys auto-disable after 14 days inactivity.
- Bills/Transfer/Card calls require institution integration config enabled.
- Agent is different from account officer. Agent attribution uses
agentCode, notaccountOfficerCode. - Virtual accounts are inbound collection aliases only. They fund the linked settlement account and cannot be used as standalone debit/balance accounts.
- Entity extra data accepts institution-specific nested JSON objects or arrays.
PUTreplaces the stored value andDELETEclears it.
3. First 3 Calls You Should Always Test
3.1 Authenticate
curl --location '{{baseurl}}/api/auth/v1/authenticate' \
--header 'Content-Type: application/json' \
--data '{
"clientId": "YOUR_CLIENT_ID",
"clientSecret": "YOUR_CLIENT_SECRET"
}'
3.2 Simple Read Health Check
curl --location '{{baseurl}}/api/product/v1/searchproducts?PageNumber=1&PageSize=1' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'request-reference: health-001' \
--header 'Content-Type: application/json'
3.3 Account Search Smoke Test
curl --location '{{baseurl}}/api/account/v1/searchaccount?PageNumber=1&PageSize=1' \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'request-reference: health-002' \
--header 'Content-Type: application/json'
4. End-to-End Workflows (Copy and Execute)
4.1 Workflow A: Customer + Account + Balance
Step A1: Create customer and account
POST /api/account/v1/createcustomeraccount
Minimum body:
{
"lastName": "Doe",
"firstName": "Jane",
"accountName": "Jane Doe",
"branchCode": "101",
"productCode": "301",
"accountOfficerStaffID": "0015245"
}
Expected success keys:
data.iddata.accountNumberdata.customerID
Step A2: Fetch account profile
GET /api/account/v1/getbyaccountnumber?AccountNumber={accountNumber}
Step A3: Fetch account balance
GET /api/account/v1/getaccountbalancebyaccountnumber?AccountNumber={accountNumber}
Agent Lifecycle Quick Flow
Use this when the institution wants to attribute loan origination to a field agent:
POST /api/agent/v1/addGET /api/agent/v1/search?AgentCode={agentCode}- Pass optional
agentCodeonPOST /api/loanaccount/v1/addorPUT /api/loanaccount/v1/update - Read back
agentCode,agentName, andagentIDfromGET /api/loanaccount/v1/search
4.2 Workflow B: Create Virtual Account
Step B1: Create virtual account
POST /api/account/v1/createvirtualaccount
Recommended body:
{
"parentAccountNumber": "1000000009",
"accountName": "Merchant VAS",
"referenceNumber": "VAS-REF-001",
"lastName": "Merchant",
"firstName": "Main",
"otherNames": "Store 1",
"phoneNumber": "08000000000",
"email": "merchant@example.com"
}
Core backend rules:
parentAccountNumbermust resolve to a valid corporate parent account, unless the API key is already bound to a parent account.- Virtual account creation is for inbound NIBSS NIP/NPS collection only.
- Only the base collection type is supported for new integrations. Do not send wallet/enhanced-proxy variants.
ProductID/productCodeis not part of virtual account creation.referenceNumbermust be unique when supplied.accountNumberin response is now the generatedVirtualAccountNumber.
Step B2: Search/verify
GET /api/account/v1/getbyaccountnumber?AccountNumber={virtualAccountNumber}
Virtual-account success indicators:
data.isVirtualAccount = truedata.virtualAccountIDis returneddata.settlementAccountNumberis parent settlement account numberdata.accountNameis returned as{virtual account name}/{corporate customer name}data.canHoldBalance = falsedata.canDebit = falsedata.historyMode = credits-only
4.3 Workflow C: Local Funds Transfer
Step C1: Execute transfer
POST /api/transfer/v1/localfundtransfer
{
"debitAccount": "1000000001",
"creditAccount": "1000000002",
"amount": 5000,
"narration": "Local transfer",
"postingsTransactionType": 3
}
postingsTransactionType:
1=GLCustomer2=GLGL3=CustomerCustomer
Virtual-account rule:
creditAccountmay be a virtual account for inbound collection into its settlement account.debitAccountcannot be a virtual account.
Step C2: Check TSQ (local)
GET /api/transfer/v1/tsq/local?referenceNumber={referenceNumber}
Success indicator:
data.isSuccessful = true
Step C3: Handle a Fraud Copilot AML hold
When Fraud Copilot returns 202 Accepted with data.statusCode = "AML_HOLD", no funds moved. Wait for staff approval, then retry the unchanged request with:
{
"amlApprovalReference": "AML-26caaadad76043d596bd"
}
4.4 Workflow D: Outward Transfer + TSQ
Step D1: Name enquiry (interbank)
GET /api/transfer/v1/nameenquiry?...
Step D2: Outward transfer
POST /api/transfer/v1/outwardtransfer
{
"nameEnquiryRef": "NE-123",
"originatorAccountNumber": "1000000001",
"originatorAccountName": "John Doe",
"beneficiaryAccountNumber": "0000014575",
"beneficiaryAccountName": "Test Beneficiary",
"destinationInstitutionCode": "TSTBNK",
"beneficiaryBankName": "Test Bank",
"transactionReference": "TX-123-UNIQUE",
"amount": 1000,
"originatorNarration": "Transfer",
"beneficiaryNarration": "Transfer"
}
Rule:
originatorAccountNumbermust be a real settlement/customer account. Virtual accounts cannot originate outward transfers.
Step D3: TSQ
GET /api/transfer/v1/tsq?transactionRef={transactionReference}
Final state field:
data.processingStatus
Interpretation:
Processed-> successReversed-> failed and reversedPending/PendingTSQ/Processing-> retry TSQConfirmManually-> check settlement/manual report
If the initial outward request returns 202 Accepted with data.statusCode = "AML_HOLD", the gateway has not been called. Wait for staff approval and retry the unchanged payload with amlApprovalReference.
4.5 Workflow E: Bills Payment + Token + TSQ
Step E1: Fetch billers
GET /api/bills/v1/billers
Step E2: Customer info validation
GET /api/bills/v1/getcustomerinformation?...
Step E3: Vend
POST /api/bills/v1/vend
{
"accountNumber": "1000001579",
"paymentReference": "BILL-UNIQUE-001",
"amount": 2000,
"packageIdentifier": "COMPACT_PLUS",
"billerIdentifier": "DSTV",
"customerId": "0101160313181"
}
Step E4: TSQ if not final
POST /api/bills/v1/tsq
Step E5: Token retrieval (electricity)
GET /api/bills/v1/gettoken?PaymentReference=BILL-UNIQUE-001
4.6 Workflow F: Card Management
Step F1: Link card to account
POST /api/card/v1/addcardtoaccount
Step F2: Search cards
GET /api/card/v1/searchcards?accountNumber=...
Step F3: Provider-specific actions
- Interswitch channel update:
PUT /api/card/v1/interswitch/updatecardchannelaccess
- Providus set pin:
PUT /api/card/v1/providus/setcardpin
- Providus block/unblock:
PUT /api/card/v1/providus/blockunblockcard
Step F4: Webhook callbacks (middleware)
/cba/cards/interswitch/transaction-feedback/cba/cards/interswitch/lifecycle-feedback/cba/cards/providus/transaction-feedback/cba/cards/providus/lifecycle-feedback
4.7 Workflow G: Loan Lifecycle
- Add loan:
POST /api/loanaccount/v1/add - Loan credit bureau review when CRC is enabled and configured:
GET /api/loanaccount/v1/loancreditbureau?loanAccountNumber={accountNumber} - Loan AI review when Credit Brain is enabled and an AI provider is configured:
GET /api/loanaccount/v1/loanaireview?loanAccountNumber={accountNumber} - Mandate initiation in the institution workflow when Mono or Recuva mandate integration is enabled and configured.
- Approve loan through the institution workflow.
- Generate loan certificate / offer letter when needed:
GET /api/loanaccount/v1/view-certificate/{id} - Disburse:
POST /api/loanaccount/v1/disburseloan - Repay:
POST /api/loanaccount/v1/repayloan - Early repayment (optional):
POST /api/loanaccount/v1/earlyrepaymentloan - Search:
GET /api/loanaccount/v1/search - Schedule:
GET /api/loanaccount/v1/viewloanschedule - Add group loan:
POST /api/loanaccount/v1/addgrouploan - Group credit bureau review:
GET /api/loanaccount/v1/grouploancreditbureau?groupLoanID={id} - Group AI review:
GET /api/loanaccount/v1/grouploanaireview?groupLoanID={id} - Disburse group loan:
POST /api/loanaccount/v1/disbursegrouploan - Repay group loan:
POST /api/loanaccount/v1/repaygrouploan - Search group loans:
GET /api/loanaccount/v1/searchgrouploan
Group Loan Payloads
Add group loan: POST /api/loanaccount/v1/addgrouploan
{
"groupLoanProductID": 1,
"name": "Women Cooperative Group A",
"referenceNumber": "GL-REF-001",
"participants": [
{
"loanRequest": {
"accountID": 101,
"productID": 12,
"accountOfficerID": 5,
"referenceNumber": "LN-REF-001",
"oracleNumber": "ORC-001",
"lendingModel": 1,
"economicSector": 0,
"failedRepaymentGracePeriod": 3,
"principalAmount": 250000,
"startDate": "2026-03-03",
"interestAccrualStartDate": "2026-03-03",
"firstRepaymentDate": "2026-04-03",
"principalRepaymentType": 3,
"principalRepaymentEvery": 1,
"principalRepaymentFrequency": 2,
"principalRepaymentTenure": 12,
"overrideProductInterestRate": false,
"applicableInterestID": 1,
"defaultInterestRate": 2.5,
"rateBasis": 0,
"interestComputationModel": 1,
"interestPaymentType": 3,
"interestPaymentEvery": 1,
"interestPaymentEveryFrequency": 2,
"interestPaymentDuration": 12,
"allowLoanFee": true,
"loanFeeID": 1,
"ignoreProductDefaultMoratorium": true,
"moratorium": 0,
"requiredSecurityDepositAmount": 5000,
"collateralPledge": false,
"collateralType": 0,
"collateralValuation": 0,
"collateralDescription": "N/A",
"allowDisbursementToGL": false,
"disbursementGLID": null,
"repaymentTrackers": 30,
"loanGuarantors": [11, 12],
"loanDocuments": [],
"notes": "Participant 1 loan request"
},
"preferredMonoReference": "MONO-PARTICIPANT-001"
}
],
"notes": "API add group loan account"
}
Disburse group loan: POST /api/loanaccount/v1/disbursegrouploan
{
"groupLoanID": 1,
"referenceNumber": "GL-REF-001",
"notes": "API disburse group loan"
}
Repay group loan: POST /api/loanaccount/v1/repaygrouploan
{
"groupLoanID": 1,
"participantRepayments": [
{
"id": 1001,
"schedules": [
{
"id": 2001,
"payInterest": true,
"payFee": true,
"payPrincipal": true,
"payDefault": false,
"payPenalty": false
}
],
"interestToPay": 1000,
"feeToPay": 500,
"principalToPay": 10000,
"defaultToPay": 0,
"penaltyToPay": 0,
"notes": "Participant repayment"
}
],
"notes": "API group loan repayment"
}
Search group loan: GET /api/loanaccount/v1/searchgrouploan
- Optional query params:
groupLoanID,referenceNumber,groupLoanStatus,pageNumber,pageSize - Example:
/api/loanaccount/v1/searchgrouploan?groupLoanStatus=Active&pageNumber=1&pageSize=20
Group review endpoints:
GET /api/loanaccount/v1/grouploancreditbureau?groupLoanID=1GET /api/loanaccount/v1/grouploanaireview?groupLoanID=1
Normal loan review endpoints:
GET /api/loanaccount/v1/loancreditbureau?loanAccountNumber=1000000001GET /api/loanaccount/v1/loanaireview?loanAccountNumber=1000000001
Review Endpoint Response Payloads (Full Analysis Body)
Loan credit bureau (GET /api/loanaccount/v1/loancreditbureau)
{
"status": true,
"message": "Request successful",
"data": {
"analysisType": "LoanCreditBureauAnalysis",
"generatedAtUtc": "2026-03-03T11:40:00Z",
"loanSnapshot": {},
"creditBureau": {}
}
}
Loan AI review (GET /api/loanaccount/v1/loanaireview)
{
"status": true,
"message": "Request successful",
"data": {
"analysisType": "LoanAiCreditReviewAnalysis",
"generatedAtUtc": "2026-03-03T11:40:00Z",
"subjectSnapshot": {},
"creditBureau": {},
"review": "Full AI credit analysis text"
}
}
Loan certificate / offer letter (GET /api/loanaccount/v1/view-certificate/{ID})
{
"status": true,
"message": "Request successful",
"data": {
"id": "12",
"loanAccountNumber": "1000000001",
"isRestructure": false,
"mimeType": "application/pdf",
"fileName": "loan-certificate-1000000001.pdf",
"document": "data:application/pdf;base64,JVBERi0xLjc..."
}
}
Notes:
- Use the loan
idreturned byGET /api/loanaccount/v1/search. - Add
?isRestructure=truewhen the{ID}belongs to a loan restructure record instead of a booked loan.
Group loan credit bureau (GET /api/loanaccount/v1/grouploancreditbureau)
{
"status": true,
"message": "Request successful",
"data": {
"analysisType": "GroupLoanCreditBureauAnalysis",
"generatedAtUtc": "2026-03-03T11:40:00Z",
"groupLoanSnapshot": {},
"creditBureau": {}
}
}
Group loan AI review (GET /api/loanaccount/v1/grouploanaireview)
{
"status": true,
"message": "Request successful",
"data": {
"analysisType": "GroupLoanAiCreditReviewAnalysis",
"generatedAtUtc": "2026-03-03T11:40:00Z",
"subjectSnapshot": {},
"creditBureau": {},
"review": "Full AI credit analysis text"
}
}
Group Loan Enums
groupLoanStatus(searchgrouploan):PendingApproval,Approved,Rejected,Active,Delinquent,Closed,WrittenOff,Restructured,InRecovery,Canceled,MaturedlendingModel:0=CreditUnions,1=Individual,2=NeighbourhoodAndSmallGroupRevolvingFunds,3=Other,4=SolidarityGroup,5=Staff,6=VillageBanking,7=WholesaleLendingprincipalRepaymentType/interestPaymentType:0=EndOfContract,1=ProRated,2=Upfront,3=EqualMonthlyInstallmentprincipalRepaymentFrequency/interestPaymentEveryFrequency:0=Days,1=Weeks,2=Months,3=YearsinterestComputationModel:0=FixedMethod,1=ReducingBalanceMethod,2=ReducingBalanceButEqualMethodrateBasis:0=Annual,1=PerPeriodmoratorium:0=False,1=True_PrincipalOnly,2=True_InterestOnly,3=True_PrincipalEtInterestcollateralType:0=RealEstate_LandAndBuilding,1=Automobile,2=PlantAndEquipment,3=NaturalReserves,4=MarketableSecurities,5=AccountReceivablesAndInventories,6=Cash,7=PersonalGuarantees,8=PostDatedCheques,9=Domicilliation
4.8 Workflow H: Fixed Deposit Lifecycle
- Add FD:
POST /api/fixeddepositaccount/v1/add - Top-up:
POST /api/fixeddepositaccount/v1/topup - Update:
PUT /api/fixeddepositaccount/v1/update - Liquidate:
POST /api/fixeddepositaccount/v1/liquidate - Search:
GET /api/fixeddepositaccount/v1/search - Generate certificate when needed:
GET /api/fixeddepositaccount/v1/view-certificate/{id}/{type}
Fixed deposit certificate (GET /api/fixeddepositaccount/v1/view-certificate/{ID}/{type})
{
"status": true,
"message": "Request successful",
"data": {
"id": "41",
"contractNo": "23000119482",
"accountName": "12 Months Fixed Deposit",
"type": "PDF",
"mimeType": "application/pdf",
"fileName": "fixed-deposit-certificate-41.pdf",
"document": "data:application/pdf;base64,JVBERi0xLjc..."
}
}
Notes:
- Use the fixed deposit
idreturned byGET /api/fixeddepositaccount/v1/search. {type}acceptsPDForExcel.
4.9 Workflow I: Reporting
- Statement:
GET /api/report/v1/requestcustomeraccountstatement - Export statement:
GET /api/report/v1/exportcustomerstatement - Transaction receipt:
GET /api/report/v1/gettransactionreceipt - Account history:
GET /api/report/v1/requestcustomeraccounthistoryreport - Transaction callover:
GET /api/report/v1/gettransactioncalloverreport - Loan expectation/tracking:
GET /api/report/v1/getloanexpectationreport,GET /api/report/v1/getloantrackingreport - Savings accrual:
GET /api/report/v1/getsavingsaccrualhistory
Virtual-account reporting rule:
requestcustomeraccounthistoryreportaccepts a virtual account number and returns credits-only history for that alias.requestcustomeraccountstatementandexportcustomerstatementreject virtual account numbers because the balance lives only on the settlement account.
5. Integration Configuration Checklist (Must Pass)
5.1 Bills
Required minimum:
BILLS_PAYMENT_ENABLED=trueBILLS_PAYMENT_BASE_URL- At least one provider enabled (
..._ENABLED=true) - Provider auth/header json configured
- Provider ledger or default ledger configured
Bills provider keys
providuscoralpayflutterwaveninepsbnibss_psspnibss_banks
5.2 Transfer
Required minimum:
TRANSFER_ENABLED=trueTRANSFER_BASE_URL- At least one provider enabled (
easypay/providus) - Provider auth/header json configured
- Settlement ledger configured
5.3 Cards
Required minimum:
CARD_ENABLED=trueCARD_BASE_URL- Provider enabled (
interswitchorprovidus) - Provider headers configured
- Settlement/issuance ledger configured where needed
5.4 Required Shared Gateway Keys
BILLS_PAYMENT_SHARED_GATEWAY_KEYTRANSFER_SHARED_GATEWAY_KEYCARD_SHARED_GATEWAY_KEY
7. Complete Endpoint List
{
"auth": [{ "method": "POST", "path": "/api/auth/v1/authenticate" }],
"account": [
{ "method": "POST", "path": "/api/account/v1/createcustomeraccount" },
{ "method": "POST", "path": "/api/account/v1/createaccount" },
{
"method": "POST",
"path": "/api/account/v1/creategroupcustomerinformation"
},
{ "method": "PUT", "path": "/api/account/v1/updatecustomeraccount" },
{ "method": "PUT", "path": "/api/account/v1/updatecustomerinformation" },
{
"method": "PUT",
"path": "/api/account/v1/updategroupcustomerinformation"
},
{ "method": "PUT", "path": "/api/account/v1/activate" },
{ "method": "PUT", "path": "/api/account/v1/deactivate" },
{ "method": "PUT", "path": "/api/account/v1/unfreeze" },
{ "method": "GET", "path": "/api/account/v1/searchaccount" },
{
"method": "GET",
"path": "/api/account/v1/getaccountbalancebyaccountnumber"
},
{ "method": "GET", "path": "/api/account/v1/getbyaccountnumber" },
{
"method": "GET",
"path": "/api/account/v1/getextendedbalancebyaccountnumber"
},
{ "method": "GET", "path": "/api/account/v1/searchaccountofficers" },
{ "method": "GET", "path": "/api/account/v1/searchgroupcustomers" },
{ "method": "GET", "path": "/api/account/v1/searchindividualcustomers" },
{ "method": "GET", "path": "/api/account/v1/listbranches" },
{ "method": "GET", "path": "/api/account/v1/searchbranches" },
{ "method": "POST", "path": "/api/account/v1/createvirtualaccount" }
],
"accountlien": [
{ "method": "POST", "path": "/api/accountlien/v1/placelien" },
{ "method": "POST", "path": "/api/accountlien/v1/updatelien" },
{ "method": "POST", "path": "/api/accountlien/v1/unplacelien" }
],
"accountoverdraft": [
{ "method": "POST", "path": "/api/accountoverdraft/v1/add" },
{ "method": "PUT", "path": "/api/accountoverdraft/v1/update" },
{ "method": "PUT", "path": "/api/accountoverdraft/v1/activate" },
{ "method": "PUT", "path": "/api/accountoverdraft/v1/deactivate" },
{ "method": "GET", "path": "/api/accountoverdraft/v1/search" }
],
"agent": [
{ "method": "POST", "path": "/api/agent/v1/add" },
{ "method": "PUT", "path": "/api/agent/v1/update" },
{ "method": "PUT", "path": "/api/agent/v1/change-status" },
{ "method": "DELETE", "path": "/api/agent/v1/delete/{ID}" },
{ "method": "GET", "path": "/api/agent/v1/search" }
],
"bills": [
{ "method": "GET", "path": "/api/bills/v1/billers" },
{ "method": "GET", "path": "/api/bills/v1/getcustomerinformation" },
{ "method": "POST", "path": "/api/bills/v1/vend" },
{ "method": "POST", "path": "/api/bills/v1/tsq" },
{ "method": "GET", "path": "/api/bills/v1/gettoken" },
{ "method": "GET", "path": "/api/bills/v1/search" }
],
"card": [
{ "method": "GET", "path": "/api/card/v1/searchcards" },
{ "method": "POST", "path": "/api/card/v1/addcardtoaccount" },
{
"method": "PUT",
"path": "/api/card/v1/interswitch/updatecardchannelaccess"
},
{ "method": "GET", "path": "/api/card/v1/providus/searchcards" },
{ "method": "PUT", "path": "/api/card/v1/providus/setcardpin" },
{ "method": "PUT", "path": "/api/card/v1/providus/blockunblockcard" },
{ "method": "PUT", "path": "/api/card/v1/block" },
{ "method": "PUT", "path": "/api/card/v1/unblock" },
{ "method": "DELETE", "path": "/api/card/v1/delete/{id}" },
{ "method": "POST", "path": "/cba/cards/interswitch/transaction-feedback" },
{ "method": "POST", "path": "/cba/cards/interswitch/lifecycle-feedback" },
{ "method": "POST", "path": "/cba/cards/providus/transaction-feedback" },
{ "method": "POST", "path": "/cba/cards/providus/lifecycle-feedback" }
],
"fixeddepositaccount": [
{ "method": "POST", "path": "/api/fixeddepositaccount/v1/add" },
{ "method": "POST", "path": "/api/fixeddepositaccount/v1/topup" },
{ "method": "POST", "path": "/api/fixeddepositaccount/v1/liquidate" },
{ "method": "PUT", "path": "/api/fixeddepositaccount/v1/update" },
{ "method": "GET", "path": "/api/fixeddepositaccount/v1/search" },
{
"method": "GET",
"path": "/api/fixeddepositaccount/v1/view-certificate/{ID}/{type}"
}
],
"limit": [
{ "method": "PUT", "path": "/api/limit/v1/addupdateaccountlimit" },
{ "method": "GET", "path": "/api/limit/v1/getaccountlimit" }
],
"loanaccount": [
{ "method": "POST", "path": "/api/loanaccount/v1/add" },
{ "method": "POST", "path": "/api/loanaccount/v1/disburseloan" },
{ "method": "POST", "path": "/api/loanaccount/v1/repayloan" },
{ "method": "POST", "path": "/api/loanaccount/v1/earlyrepaymentloan" },
{ "method": "POST", "path": "/api/loanaccount/v1/addgrouploan" },
{ "method": "POST", "path": "/api/loanaccount/v1/disbursegrouploan" },
{ "method": "POST", "path": "/api/loanaccount/v1/repaygrouploan" },
{ "method": "PUT", "path": "/api/loanaccount/v1/update" },
{ "method": "GET", "path": "/api/loanaccount/v1/search" },
{ "method": "GET", "path": "/api/loanaccount/v1/view-certificate/{ID}" },
{ "method": "GET", "path": "/api/loanaccount/v1/viewloanschedule" },
{ "method": "GET", "path": "/api/loanaccount/v1/searchgrouploan" },
{ "method": "GET", "path": "/api/loanaccount/v1/grouploancreditbureau" },
{ "method": "GET", "path": "/api/loanaccount/v1/grouploanaireview" },
{ "method": "GET", "path": "/api/loanaccount/v1/loancreditbureau" },
{ "method": "GET", "path": "/api/loanaccount/v1/loanaireview" }
],
"operations": [
{ "method": "GET", "path": "/api/operations/v1/searchtillaccounts" },
{
"method": "GET",
"path": "/api/operations/v1/gettillbalancebyaccountnumber"
},
{ "method": "POST", "path": "/api/operations/v1/uploaddocument" },
{ "method": "PUT", "path": "/api/operations/v1/deletedocument" },
{ "method": "POST", "path": "/api/operations/v1/sendsms" },
{ "method": "POST", "path": "/api/operations/v1/sendemail" }
],
"postings": [
{ "method": "POST", "path": "/api/postings/v1/closeaccount" },
{ "method": "POST", "path": "/api/postings/v1/posttransaction" },
{ "method": "POST", "path": "/api/postings/v1/post" },
{ "method": "POST", "path": "/api/postings/v1/reversetransaction" }
],
"product": [{ "method": "GET", "path": "/api/product/v1/searchproducts" }],
"report": [
{
"method": "GET",
"path": "/api/report/v1/requestcustomeraccountstatement"
},
{ "method": "GET", "path": "/api/report/v1/exportcustomerstatement" },
{ "method": "GET", "path": "/api/report/v1/gettransactionreceipt" },
{
"method": "GET",
"path": "/api/report/v1/requestcustomeraccounthistoryreport"
},
{ "method": "GET", "path": "/api/report/v1/gettransactioncalloverreport" },
{ "method": "GET", "path": "/api/report/v1/getloanexpectationreport" },
{ "method": "GET", "path": "/api/report/v1/getloantrackingreport" },
{ "method": "GET", "path": "/api/report/v1/getsavingsaccrualhistory" }
],
"transfer": [
{ "method": "GET", "path": "/api/transfer/v1/banks" },
{ "method": "GET", "path": "/api/transfer/v1/nameenquiry" },
{ "method": "GET", "path": "/api/transfer/v1/nameenquiry/local" },
{ "method": "POST", "path": "/api/transfer/v1/balanceenquiry" },
{ "method": "POST", "path": "/api/transfer/v1/localfundtransfer" },
{ "method": "POST", "path": "/api/transfer/v1/outwardtransfer" },
{ "method": "POST", "path": "/api/transfer/v1/fundstransfer" },
{ "method": "GET", "path": "/api/transfer/v1/tsq" },
{ "method": "GET", "path": "/api/transfer/v1/tsq/local" },
{ "method": "GET", "path": "/api/transfer/v1/search" }
],
"utility": [
{ "method": "GET", "path": "/api/utility/v1/countries" },
{ "method": "GET", "path": "/api/utility/v1/regions" },
{ "method": "GET", "path": "/api/utility/v1/cities" }
]
}
Geography Lookup
Use the utility endpoints when an integrator needs country, state/region, or city/LGA master data:
GET /api/utility/v1/countriesGET /api/utility/v1/regions?CountryCode2=NGGET /api/utility/v1/cities?RegionShortCode=LA&CountryCode2=NG
The geography endpoints are authenticated API-channel reads. They return flat lists plus recordCount.
8. Where to Get Exact Payload Contracts
Use this file for fast execution.
For exhaustive exact property-level contracts and enums from source:
9. Zero-Ambiguity Playbooks
This section is intentionally repetitive. Use it when you want exact call order.
9.1 Playbook: API Authentication and Access Validation
| Step | Action | Endpoint | Success Check |
|---|---|---|---|
| 1 | Authenticate with active API key pair | POST /api/auth/v1/authenticate | Response contains accessToken |
| 2 | Use token for a safe read call | GET /api/product/v1/searchproducts?PageNumber=1&PageSize=1 | status=true |
| 3 | Confirm request tracing header works | any secured endpoint + request-reference | Request is accepted |
Failure handling:
API key is inactive or not found: activate/regenerate API key in Operations.Unauthorized: token expired, re-authenticate.Invalid API token claims: token was not issued via API channel auth flow.
9.2 Playbook: Create Individual Customer and CASA Account
Preconditions:
BranchCodeexists and is active.ProductCodeexists and is active for account creation.AccountOfficerStaffIDexists and is active.
Call:
POST /api/account/v1/createcustomeraccount
Minimum viable payload:
{
"lastName": "Doe",
"firstName": "Jane",
"accountName": "Jane Doe",
"branchCode": "101",
"productCode": "301",
"accountOfficerStaffID": "09074"
}
Expected response keys:
data.id(GUID record id)data.accountNumberdata.customerID(business customer id)
Immediate validation calls:
GET /api/account/v1/getbyaccountnumber?AccountNumber={accountNumber}GET /api/account/v1/getaccountbalancebyaccountnumber?AccountNumber={accountNumber}
9.3 Playbook: Create Account Only (Existing Customer)
Call:
POST /api/account/v1/createaccount
Expected outcome:
- New account linked to existing customer.
- Account number returned in response data.
If documents were supplied, validate with:
POST /api/operations/v1/uploaddocumentwhen needed.
9.4 Playbook: Create Virtual Account (Collection Alias)
Call:
POST /api/account/v1/createvirtualaccount
Rules:
- Parent account must be a business/corporate account (or pre-bound on API key).
- Virtual accounts are collection aliases for inbound NIP/NPS funding only.
- Only the base collection virtual-account type is supported for new integrations.
referenceNumbermust be unique when supplied.
Validation:
GET /api/account/v1/getbyaccountnumber?AccountNumber={generatedAccountNumber}GET /api/account/v1/searchaccount?AccountNumber={generatedAccountNumber}
Restrictions expected by design:
- Virtual account should not be used as a debit-capable account.
- Virtual account should not expose balance through the virtual account number.
- Virtual account should not access disallowed loan/fixed-deposit operations.
Virtual-account response model notes:
getbyaccountnumberreturns:id= virtual-account ID for virtual queries.virtualAccountID= virtual-account ID.settlementAccountNumber= parent account number.accountName={virtual account name}/{corporate customer name}.isVirtualAccount = true.
getaccountbalancebyaccountnumberrejects virtual account numbers.searchaccountcan return virtual rows (fallback whenAccountNumbermatches virtual account):id= virtual-account ID.accountNumber= virtual account number.settlementAccountNumber= parent account number.isVirtualAccount = true.
9.5 Playbook: Update Account / Activate / Deactivate / Unfreeze
Endpoints:
PUT /api/account/v1/updatecustomeraccountPUT /api/account/v1/activatePUT /api/account/v1/deactivatePUT /api/account/v1/unfreeze
Pattern:
- Submit action payload.
- Re-query via
searchaccountorgetbyaccountnumber. - Confirm
accountStatusreflects requested operation.
Virtual-account specifics:
updatecustomeraccount.idmust be the settlement account ID. Virtual-account IDs are rejected.activate/deactivate/unfreezereject virtual account numbers. Use the settlement account number directly.
9.6 Playbook: Close Account
Call:
POST /api/postings/v1/closeaccount
Payload essentials:
accountNumberclosureReason
Post-check:
GET /api/account/v1/getbyaccountnumber?AccountNumber=...- Validate closed status and final balances.
9.7 Playbook: Local Funds Transfer (Internal)
Call:
POST /api/transfer/v1/localfundtransfer
Supports:
- Account -> Account
- Account -> Ledger
- Ledger -> Account
- Ledger -> Ledger
Core payload fields:
debitAccountcreditAccountamount(Naira)narrationpostingsTransactionType(1=GLCustomer,2=GLGL,3=CustomerCustomer)
Status check:
GET /api/transfer/v1/tsq/local?referenceNumber=...
9.8 Playbook: Interbank Transfer (Outward Transfer)
Strict sequence:
GET /api/transfer/v1/banksGET /api/transfer/v1/nameenquiryPOST /api/transfer/v1/outwardtransferGET /api/transfer/v1/tsq?transactionRef=...
TSQ decision model:
Processed: success.Pending,Processing,PendingTSQ: retry TSQ.Reversed: failed, funds reversed.Failed: failed, check reversal flag.ConfirmManually: reconcile from settlement report.
9.9 Playbook: Bills Payment (with TSQ and Token)
Strict sequence:
GET /api/bills/v1/billersGET /api/bills/v1/getcustomerinformationPOST /api/bills/v1/vendPOST /api/bills/v1/tsq(if gateway status is not final)GET /api/bills/v1/gettoken(electricity scenarios)
Money movement expectation:
- Debit from customer/settlement account.
- Credit to configured bills ledger.
- On provider failure, reversal should be triggered.
9.10 Playbook: Card Operations
Common flow:
POST /api/card/v1/addcardtoaccountGET /api/card/v1/searchcards- Provider operation:
- Interswitch:
PUT /api/card/v1/interswitch/updatecardchannelaccess - Providus:
PUT /api/card/v1/providus/setcardpin - Providus:
PUT /api/card/v1/providus/blockunblockcard
- Optional generic block/unblock/delete:
PUT /api/card/v1/blockPUT /api/card/v1/unblockDELETE /api/card/v1/delete/{id}
Middleware callback paths (must be exact):
/cba/cards/interswitch/transaction-feedback/cba/cards/interswitch/lifecycle-feedback/cba/cards/providus/transaction-feedback/cba/cards/providus/lifecycle-feedback
9.11 Playbook: Agent Lifecycle
Common flow:
POST /api/agent/v1/addGET /api/agent/v1/searchPUT /api/agent/v1/update(optional)PUT /api/agent/v1/change-status(optional)DELETE /api/agent/v1/delete/{ID}only when no loans are attached
Business rule reminder:
- Agents cannot log in.
- CoreWave generates the unique institution agent code.
- Agent is different from account officer.
9.12 Playbook: Loan Lifecycle
Strict sequence:
POST /api/loanaccount/v1/addGET /api/loanaccount/v1/loancreditbureau?loanAccountNumber={accountNumber}when bureau review is enabledGET /api/loanaccount/v1/loanaireview?loanAccountNumber={accountNumber}when AI review is enabled- Complete approval in the institution flow
POST /api/loanaccount/v1/disburseloanPOST /api/loanaccount/v1/repayloan(as needed)POST /api/loanaccount/v1/earlyrepaymentloan(optional)PUT /api/loanaccount/v1/update(optional)GET /api/loanaccount/v1/view-certificate/{id}GET /api/loanaccount/v1/viewloanscheduleGET /api/loanaccount/v1/searchPOST /api/loanaccount/v1/addgrouploanPOST /api/loanaccount/v1/disbursegrouploanPOST /api/loanaccount/v1/repaygrouploanGET /api/loanaccount/v1/searchgrouploanGET /api/loanaccount/v1/grouploancreditbureau?groupLoanID={id}GET /api/loanaccount/v1/grouploanaireview?groupLoanID={id}
Business rule reminder:
linkedNumbermust be the linked account number belonging to the loan owner.agentCodeis optional and is separate fromaccountOfficerCode.
9.13 Playbook: Fixed Deposit Lifecycle
Strict sequence:
POST /api/fixeddepositaccount/v1/addPOST /api/fixeddepositaccount/v1/topupPUT /api/fixeddepositaccount/v1/updatePOST /api/fixeddepositaccount/v1/liquidateGET /api/fixeddepositaccount/v1/searchGET /api/fixeddepositaccount/v1/view-certificate/{id}/{type}
9.14 Playbook: Overdraft and Lien
Overdraft:
- Add:
POST /api/accountoverdraft/v1/add - Update:
PUT /api/accountoverdraft/v1/update - Activate/Deactivate:
PUT /api/accountoverdraft/v1/activate,PUT /api/accountoverdraft/v1/deactivate - Search:
GET /api/accountoverdraft/v1/search
Lien:
- Place:
POST /api/accountlien/v1/placelien - Update:
POST /api/accountlien/v1/updatelien - Unplace:
POST /api/accountlien/v1/unplacelien
9.14 Playbook: Statements and Reports
Primary endpoints:
GET /api/report/v1/requestcustomeraccountstatementGET /api/report/v1/exportcustomerstatementGET /api/report/v1/gettransactionreceiptGET /api/report/v1/requestcustomeraccounthistoryreportGET /api/report/v1/gettransactioncalloverreportGET /api/report/v1/getloanexpectationreportGET /api/report/v1/getloantrackingreportGET /api/report/v1/getsavingsaccrualhistory
10. Institution Configuration Blueprint (Onboarding Template)
Use this template when onboarding a new institution. Keep providers disabled by default.
{
"BILLS_PAYMENT_ENABLED": "false",
"BILLS_PAYMENT_BASE_URL": "https://bills-middleware.example.com",
"BILLS_PAYMENT_DEFAULT_PROVIDER": "providus",
"BILLS_PAYMENT_DEFAULT_LEDGER_CODE": "",
"BILLS_PAYMENT_PROVIDER_PROVIDUS_ENABLED": "false",
"BILLS_PAYMENT_PROVIDER_PROVIDUS_AUTH_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_PROVIDUS_HEADERS_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_PROVIDUS_AUTHORIZATION": "",
"BILLS_PAYMENT_PROVIDER_PROVIDUS_LEDGER_CODE": "",
"BILLS_PAYMENT_PROVIDER_CORALPAY_ENABLED": "false",
"BILLS_PAYMENT_PROVIDER_CORALPAY_AUTH_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_CORALPAY_HEADERS_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_CORALPAY_AUTHORIZATION": "",
"BILLS_PAYMENT_PROVIDER_CORALPAY_LEDGER_CODE": "",
"BILLS_PAYMENT_PROVIDER_FLUTTERWAVE_ENABLED": "false",
"BILLS_PAYMENT_PROVIDER_FLUTTERWAVE_AUTH_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_FLUTTERWAVE_HEADERS_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_FLUTTERWAVE_AUTHORIZATION": "",
"BILLS_PAYMENT_PROVIDER_FLUTTERWAVE_LEDGER_CODE": "",
"BILLS_PAYMENT_PROVIDER_NINEPSB_ENABLED": "false",
"BILLS_PAYMENT_PROVIDER_NINEPSB_AUTH_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_NINEPSB_HEADERS_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_NINEPSB_AUTHORIZATION": "",
"BILLS_PAYMENT_PROVIDER_NINEPSB_LEDGER_CODE": "",
"BILLS_PAYMENT_PROVIDER_NIBSS_PSSP_ENABLED": "false",
"BILLS_PAYMENT_PROVIDER_NIBSS_PSSP_AUTH_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_NIBSS_PSSP_HEADERS_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_NIBSS_PSSP_AUTHORIZATION": "",
"BILLS_PAYMENT_PROVIDER_NIBSS_PSSP_LEDGER_CODE": "",
"BILLS_PAYMENT_PROVIDER_NIBSS_BANKS_ENABLED": "false",
"BILLS_PAYMENT_PROVIDER_NIBSS_BANKS_AUTH_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_NIBSS_BANKS_HEADERS_JSON": "{}",
"BILLS_PAYMENT_PROVIDER_NIBSS_BANKS_AUTHORIZATION": "",
"BILLS_PAYMENT_PROVIDER_NIBSS_BANKS_LEDGER_CODE": "",
"BILLS_PAYMENT_NOTIFICATION_PHONE": "",
"BILLS_PAYMENT_NOTIFICATION_EMAIL": "",
"TRANSFER_ENABLED": "false",
"TRANSFER_BASE_URL": "https://transfer-middleware.example.com",
"TRANSFER_DEFAULT_PROVIDER": "easypay",
"TRANSFER_DEFAULT_LEDGER_CODE": "",
"TRANSFER_PROVIDER_EASYPAY_ENABLED": "false",
"TRANSFER_PROVIDER_EASYPAY_AUTH_JSON": "{}",
"TRANSFER_PROVIDER_EASYPAY_HEADERS_JSON": "{}",
"TRANSFER_PROVIDER_EASYPAY_LEDGER_CODE": "",
"TRANSFER_PROVIDER_PROVIDUS_ENABLED": "false",
"TRANSFER_PROVIDER_PROVIDUS_AUTH_JSON": "{}",
"TRANSFER_PROVIDER_PROVIDUS_HEADERS_JSON": "{}",
"TRANSFER_PROVIDER_PROVIDUS_LEDGER_CODE": "",
"CARD_ENABLED": "false",
"CARD_BASE_URL": "https://cards-middleware.example.com",
"CARD_DEFAULT_PROVIDER": "providus",
"CARD_ISSUANCE_CHARGE": "0",
"CARD_ISSUANCE_CHARGE_LEDGER_CODE": "",
"CARD_TRANSACTION_SETTLEMENT_LEDGER_CODE": "",
"CARD_PROVIDER_INTERSWITCH_ENABLED": "false",
"CARD_PROVIDER_INTERSWITCH_HEADERS_JSON": "{}",
"CARD_PROVIDER_PROVIDUS_ENABLED": "false",
"CARD_PROVIDER_PROVIDUS_HEADERS_JSON": "{}",
"API_BYPASS_APPROVALS": "false"
}
Provider auth guidance:
- Some providers expect
clientId/clientSecret. - Some expect
publicKey/secretKey. - Store provider-specific auth shape inside
*_AUTH_JSONexactly as middleware expects.
11. Transaction AdditionalMetadata Contract (Transfer + Bills)
Transaction history must carry contextual metadata in Transaction.AdditionalMetadata as JSON.
11.1 Transfer Metadata Example
{
"channel": "transfer",
"provider": "easypay",
"transfer_type": "outward",
"bank_code_to": "058",
"bank_to": "Guaranty Trust Bank",
"account_name_to": "John Beneficiary",
"account_number_to": "0123456789",
"account_name_from": "Jane Originator",
"account_number_from": "1000000001",
"originator_bvn": "",
"beneficiary_bvn": "",
"transaction_reference": "TX-123",
"name_enquiry_ref": "NE-123",
"session_id": "",
"processing_status": "Pending",
"narration_originator": "Transfer",
"narration_beneficiary": "Transfer"
}
11.2 Bills Metadata Example
{
"channel": "bills",
"provider": "providus",
"biller_identifier": "DSTV",
"biller_name": "DSTV",
"package_identifier": "COMPACT_PLUS",
"package_name": "Compact Plus",
"customer_id": "0101160313181",
"customer_name": "John Viewer",
"payment_reference": "BILL-123",
"posting_reference": "",
"transaction_id": "",
"vend_status": "Pending",
"token": "",
"token_units": 0
}
Notification usage guidance:
- SMS/Email templates should read from
AdditionalMetadata. - Transfer notifications should include destination bank/name/account from metadata.
- Bills notifications should include biller, package, customer id/name, and token (when available).
11.1 Entity Extra Data
Use entity extra data when an institution needs to attach custom nested JSON fields to a product, customer, account, loan, or fixed-deposit record.
Primary endpoints:
GET /api/entity-additional-metadata/v1/supported-entity-typesGET /api/entity-additional-metadata/v1/{entityType}/{entityId}PUT /api/entity-additional-metadata/v1/{entityType}/{entityId}DELETE /api/entity-additional-metadata/v1/{entityType}/{entityId}
Operational rules:
additionalMetadatamust be a JSON object or array.PUTreplaces the stored JSON value.- Fetch first when an integration needs to merge individual keys.
- Use
DELETEto clear the value. - Maximum payload size is 64 KB.
- All access is institution-scoped from the API-channel token.
For supported entity types and copy-ready requests, see Entity Extra Data.
12. Approvals Behavior for API Channel
Controlled by configuration:
API_BYPASS_APPROVALS
Behavior:
true: API-initiated operations bypass approval workflow.false: API-initiated operations flow through standard approval logic.
Recommendation:
- Keep
falseby default for new institutions. - Enable
trueonly for institutions with signed risk acceptance.
12.1 Fraud Copilot AML holds cannot be bypassed
When Fraud Copilot is enabled, AML holds apply before API and portal money movement even when API_BYPASS_APPROVALS=true.
- Staff release requires
approve-aml-held-transactions. - API callers receive
202 Acceptedand retry the unchanged payload withamlApprovalReference. - Portal posting groups resume automatically after AML approval and still honor any configured posting approval queue before balances move.
13. Idempotency, Retry, and Reconciliation Rules
Idempotency keys to treat as unique:
- Header:
request-reference - Business refs:
paymentReference,transactionReference,referenceNumber
Retry strategy:
- On timeout, do not re-post blindly.
- Query search/TSQ endpoint first.
- Re-post only if no trace exists.
Reconciliation strategy:
- Transfer: use
TSQandprocessingStatus. - Bills: use
TSQ, thenSearchto inspectisReversedandrequireReversal. - Local posting: use
TSQ/localor transaction history search.
14. QA Acceptance Matrix (What Must Pass Before Go-Live)
| Area | Test | Pass Criteria |
|---|---|---|
| Auth | Authenticate with valid key | Token returned |
| Auth | Authenticate with inactive key | Rejected with clear message |
| Accounts | Create customer+account | Account number + customer id returned |
| Accounts | Upload document | Upload accepted and retrievable/deletable |
| Transfers | Local transfer | Debit/Credit posted and TSQ local successful |
| Transfers | Outward transfer success path | TSQ reaches Processed |
| Transfers | Outward transfer failure path | Reversal status is visible when failed |
| Bills | Vend success path | Successful status with traceable refs |
| Bills | Vend failure path | Reversal path works and searchable |
| Bills | Electricity token | Token retrievable and sent via notifications |
| Cards | Add/search/block/unblock/set pin | Provider actions reflected in state |
| Loans | Add/disburse/repay/search/schedule | All states consistent |
| FD | Add/topup/update/liquidate/search | All operations consistent |
| Reports | Statement + export + receipt | Data rendered and export streams correctly |
| Limits | Add/update/get account transfer limit | Values persist and are enforced |
| Metadata | Add/fetch/replace/clear extra data | Nested JSON persists and stays tenant-scoped |
| Security | API key inactivity auto-disable | Key disabled after 14 days of no usage |
15. Reference Material
Use resources in this order:
- This document: execution flow and operational behavior.
- The API Channel Reference (
api-channel-reference): endpoint inventory, request/response formats, and validation rules. - The Postman collection available for download from the site navigation header.