Documents & Payments
Manual payment claims, repayment tracking, and a legacy multipart document upload for post-submit extras.
Upload supporting document
POST /api/loans/{loanId}/documentsLegacy / post-submit extras. Prefer Utils → Upload file
(POST /api/uploads) and pass S3 keys on loan submit.
Required docs are product-gated at submit time (K-12: utilityBill + idCard;
Exam/Graduate: see submit descriptions). This multipart route can still attach
extras after submit. Max 10MB.
documentType: e.g. ExamInvoice, AdmissionLetter, or UtilityBill.
Headers
| Header | Value |
|---|---|
Accept | application/json |
Authorization | Bearer {parentAccessToken} |
No Content-Type header, the browser sets its own multipart boundary for you.
Form fields
| Field | Description |
|---|---|
documentType | ExamInvoice, AdmissionLetter, or UtilityBill. |
file | The document, max 10MB. |
Response 200
{
"success": true,
"message": "Request successful",
"data": "ExamInvoice uploaded.",
"errors": [],
"statusCode": 200
}Try it
Submit manual payment claim
POST /api/loans/{loanId}/paymentsRecords an external payment for admin reconciliation, the loan’s balance only updates after EdPay confirms it.
Headers
| Header | Value |
|---|---|
Accept | application/json |
Authorization | Bearer {parentAccessToken} |
No Content-Type header, the browser sets its own multipart boundary for you.
Form fields
| Field | Description |
|---|---|
amount | Amount paid. |
paymentDate | ISO date. |
referenceNote | Free text, e.g. a bank transfer reference. |
proofFile | Optional attachment. |
Response 201
{
"success": true,
"message": "Resource created successfully",
"data": {
"id": "d9e8f7a6-b5c4-3210-fedc-ba9876543210",
"amount": 50000.00,
"paymentDate": "2025-09-01T00:00:00Z",
"referenceNote": "Bank transfer ref 12345",
"hasProofDocument": true,
"status": "Pending",
"confirmedAt": null,
"rejectionReason": null
},
"errors": [],
"statusCode": 201
}status starts at Pending, see Payment history for how it
progresses.
Try it
Payment history
GET /api/loans/{loanId}/paymentsDespite the name, this returns the full loan
detail response, not just an array
of payments. If you only need the payment claims, read data.paymentHistory off
the result rather than treating the whole response as a list.
Headers
| Header | Value |
|---|---|
Accept | application/json |
Authorization | Bearer {parentAccessToken} |
Response 200
{
"success": true,
"message": "Request successful",
"data": {
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"applicationNumber": "LN-20250901-0001",
"...": "... same fields as loan detail ...",
"paymentHistory": [
{
"id": "d9e8f7a6-b5c4-3210-fedc-ba9876543210",
"amount": 50000.00,
"paymentDate": "2025-09-01T00:00:00Z",
"referenceNote": "Bank transfer ref 12345",
"hasProofDocument": true,
"status": "Pending",
"confirmedAt": null,
"rejectionReason": null
}
]
},
"errors": [],
"statusCode": 200
}Try it
Repayment schedule
GET /api/loans/{loanId}/repayment-scheduleThe installment plan, with due dates and payment status for each installment.
Headers
| Header | Value |
|---|---|
Accept | application/json |
Authorization | Bearer {parentAccessToken} |
Response 200
{
"success": true,
"message": "Request successful",
"data": [
{
"installmentNumber": 1,
"amount": 46875.00,
"dueDate": "2025-10-01T00:00:00Z",
"status": "Successful",
"amountPaid": 46875.00,
"paidAt": "2025-10-01T08:15:00Z"
},
{
"installmentNumber": 2,
"amount": 46875.00,
"dueDate": "2025-11-01T00:00:00Z",
"status": "Scheduled",
"amountPaid": null,
"paidAt": null
}
],
"errors": [],
"statusCode": 200
}status is one of Scheduled, Processing, Successful, Failed, Retrying,
Waived.