LentMe API (v1)

Download OpenAPI specification:Download

Lending and investment API for mobile and USSD users

AdminAuth

Authentication endpoints for the LentMe admin/ops portal. Adds CAPTCHA, login throttling, and lockout protections. Issues JWTs that the admin UI can use to access protected endpoints.

Authenticates an active admin/ops user and returns a JWT. Protected with CAPTCHA and rate-limit + lockout.

Authorizations:
Bearer
Request Body schema:

Username/password credentials.

username
string or null

The username (email recommended) of the admin/ops user.

password
string or null

The plaintext password entered by the admin/ops user.

Responses

Request samples

Content type
{
  • "username": "string",
  • "password": "string"
}

Response samples

Content type
No sample

BankAccount

Provides endpoints for verifying and linking bank accounts. Secured for mobile users; ownership is enforced via the authenticated user's PublicId.

Step 1: Verifies the provided bank account and sends an OTP if valid. Enforces OTP throttling per phone (or per user if phone is unavailable).

Authorizations:
Bearer
Request Body schema:

Bank account details to verify.

userId
string <uuid>

Gets or sets the unique identifier of the user to whom the bank account belongs.

accountNumber
string or null

Gets or sets the bank account number.

bankCode
string or null

Gets or sets the code of the bank to which the account belongs. Should match a valid entry in the LentMeAPI.Models.LentMeBank model.

accountName
string or null

Gets or sets the name of the bank account holder. This is optional and may be null if auto-fetch is not available.

Responses

Request samples

Content type
{
  • "userId": "2c4a230c-5085-4924-a3e1-25fb4fc5965b",
  • "accountNumber": "string",
  • "bankCode": "string",
  • "accountName": "string"
}

Response samples

Content type
No sample

Step 2: Verifies the OTP and links the bank account to the authenticated user. Ignores any user id in the DTO; uses the caller's `PublicId` instead.

Authorizations:
Bearer
query Parameters
otpCode
string

One-time password code provided by the user.

Request Body schema:

Bank account details to link.

userId
string <uuid>

Gets or sets the unique identifier of the user to whom the bank account belongs.

accountNumber
string or null

Gets or sets the bank account number.

bankCode
string or null

Gets or sets the code of the bank to which the account belongs. Should match a valid entry in the LentMeAPI.Models.LentMeBank model.

accountName
string or null

Gets or sets the name of the bank account holder. This is optional and may be null if auto-fetch is not available.

Responses

Request samples

Content type
{
  • "userId": "2c4a230c-5085-4924-a3e1-25fb4fc5965b",
  • "accountNumber": "string",
  • "bankCode": "string",
  • "accountName": "string"
}

Response samples

Content type
No sample

BankSettings

API controller for managing bank API settings such as endpoint URLs and payloads. Restricted to admin/ops.

Adds a single bank API setting if it does not already exist.

Authorizations:
Bearer
Request Body schema:

The bank setting data to be added.

bankCode
required
string [ 1 .. 10 ] characters

Gets or sets the bank code to which this API setting applies. Must be a unique code matching the corresponding bank entity.

endpointName
required
string [ 1 .. 100 ] characters

Gets or sets the name of the API endpoint (e.g., "GetCustomerByAccount"). Used to identify the purpose of the API call.

url
required
string non-empty

Gets or sets the URL of the API endpoint used to perform bank operations. Can include placeholders like {accountNumber} for dynamic substitution.

payload
string or null

Gets or sets the optional JSON payload to be sent in the request body for POST or PUT operations. This can be null if the endpoint uses query parameters or GET requests.

Responses

Request samples

Content type
{
  • "bankCode": "string",
  • "endpointName": "string",
  • "url": "string",
  • "payload": "string"
}

Adds multiple bank API settings in bulk. Skips existing entries.

Authorizations:
Bearer
Request Body schema:

A list of bank setting DTOs to be added.

Array
bankCode
required
string [ 1 .. 10 ] characters

Gets or sets the bank code to which this API setting applies. Must be a unique code matching the corresponding bank entity.

endpointName
required
string [ 1 .. 100 ] characters

Gets or sets the name of the API endpoint (e.g., "GetCustomerByAccount"). Used to identify the purpose of the API call.

url
required
string non-empty

Gets or sets the URL of the API endpoint used to perform bank operations. Can include placeholders like {accountNumber} for dynamic substitution.

payload
string or null

Gets or sets the optional JSON payload to be sent in the request body for POST or PUT operations. This can be null if the endpoint uses query parameters or GET requests.

Responses

Request samples

Content type
[
  • {
    }
]

Disbursements

User-facing endpoints for loan disbursement. Delegates to LentMeAPI.Services.Abstractions.IDisbursementService, which persists attempts to LoanDisbursements and performs the bank call.

Disburses an approved loan to the beneficiary and returns the disbursement outcome together with any generated repayment schedule information.

Authorizations:
Bearer
Request Body schema:

The disbursement request. The controller enforces ownership by overriding UserId with the caller's PublicUserId from JWT. The service should create a new row in LoanDisbursements (with a generated business LoanId and unique ExternalReference), call the bank, and update Status, ResponseBody, ResponseCode, and DisbursedAt.

userId
string <uuid>

Borrower/user identifier.

bankCode
string or null

Beneficiary bank code (used to resolve endpoint/payload from BankSettings).

accountNumber
string or null

Beneficiary account number to credit.

amount
number <double>

Approved principal amount to disburse.

loanTerm
integer <int32>

Loan term in months (e.g., 1, 3, or 6).

interestRate
number or null <double>

Interest rate to apply for the term (e.g., 0.07, 0.09, 0.11). If null, the service will infer by term using platform defaults.

narration
string or null

Optional narration/description shown on the transfer.

firstDueDateUtc
string or null <date-time>

Optional first due date; if null, the schedule starts one month after disbursement date.

Responses

Request samples

Content type
{
  • "userId": "2c4a230c-5085-4924-a3e1-25fb4fc5965b",
  • "bankCode": "string",
  • "accountNumber": "string",
  • "amount": 0.1,
  • "loanTerm": 0,
  • "interestRate": 0.1,
  • "narration": "string",
  • "firstDueDateUtc": "2019-08-24T14:15:22Z"
}

Response samples

Content type
No sample

LentMeAuth

Provides authentication and user account management endpoints (register, login, OTP, PIN reset), including device-binding and location step-up auth for mobile users. Uses LentMeAPI.Models.LentMeUser.PublicId (GUID) as the JWT subject and name identifier.

Registers a new user after OTP verification.

Public endpoint.

Authorizations:
Bearer
Request Body schema:
phoneNumber
string or null

Gets or sets the user's phone number.

firstName
string or null

Gets or sets the user's first name.

lastName
string or null

Gets or sets the user's last name.

gender
string or null

Gets or sets the user's gender.

dateOfBirth
string <date-time>

Gets or sets the user's date of birth.

address
string or null

Gets or sets the user's physical address.

pin
string or null

Gets or sets the PIN used for account security during registration.

Responses

Request samples

Content type
{
  • "phoneNumber": "string",
  • "firstName": "string",
  • "lastName": "string",
  • "gender": "string",
  • "dateOfBirth": "2019-08-24T14:15:22Z",
  • "address": "string",
  • "pin": "string"
}

Response samples

Content type
No sample

Authenticates a user and issues a JWT. If first login, binds the device automatically. If device changed, issues an OTP challenge (`2101`). If location far from last known, issues an OTP challenge (`2102`).

Public endpoint.

Authorizations:
Bearer
Request Body schema:
phoneNumber
required
string non-empty

User's phone number.

pin
required
string non-empty

User's secret PIN.

deviceId
string or null

Stable device identifier from the mobile app (e.g., vendor/device ID).

deviceModel
string or null

Free-form device model (e.g., iPhone 13).

platform
string or null

Platform/OS (e.g., iOS, Android 14).

latitude
number or null <double>

Current latitude (optional).

longitude
number or null <double>

Current longitude (optional).

Responses

Request samples

Content type
{
  • "phoneNumber": "string",
  • "pin": "string",
  • "deviceId": "string",
  • "deviceModel": "string",
  • "platform": "string",
  • "latitude": 0.1,
  • "longitude": 0.1
}

Response samples

Content type
No sample

Verifies device/location OTP challenge and returns JWT upon success.

Public endpoint.

Authorizations:
Bearer
Request Body schema:
challengeId
required
string <uuid>

Challenge id returned from the login step.

code
required
string [ 1 .. 10 ] characters

6-digit OTP code sent to the user's phone.

Responses

Request samples

Content type
{
  • "challengeId": "007cfdcc-a46d-4340-a4c6-216ec2e4009c",
  • "code": "string"
}

Response samples

Content type
No sample

Sends an OTP to the supplied phone number (generic flow). CAPTCHA-protected via LentMeAPI.Security.CaptchaProtectedAttribute when enabled.

Public endpoint.

Authorizations:
Bearer
Request Body schema:
phoneNumber
string or null

Gets or sets the phone number to which the OTP should be sent.

Responses

Request samples

Content type
{
  • "phoneNumber": "string"
}

Response samples

Content type
No sample

Verifies an OTP for the phone number.

Public endpoint.

Authorizations:
Bearer
Request Body schema:
phoneNumber
string or null

Gets or sets the phone number associated with the OTP.

code
string or null

Gets or sets the OTP code provided by the user for verification.

Responses

Request samples

Content type
{
  • "phoneNumber": "string",
  • "code": "string"
}

Response samples

Content type
No sample

Starts the "forgot PIN" flow: issues an OTP for PIN reset. CAPTCHA-protected via LentMeAPI.Security.CaptchaProtectedAttribute.

Public endpoint.

Authorizations:
Bearer
Request Body schema:
phoneNumber
string or null

Gets or sets the phone number to which the OTP should be sent.

Responses

Request samples

Content type
{
  • "phoneNumber": "string"
}

Response samples

Content type
No sample

Verifies the PIN-reset OTP and returns a short-lived reset token. Locks out after repeated failures within a window.

Public endpoint.

Authorizations:
Bearer
Request Body schema:
phoneNumber
string or null

Gets or sets the phone number associated with the OTP.

code
string or null

Gets or sets the OTP code provided by the user for verification.

Responses

Request samples

Content type
{
  • "phoneNumber": "string",
  • "code": "string"
}

Response samples

Content type
No sample

Completes a PIN reset using a short-lived reset token obtained from `forgot-pin/verify-otp`.

Public endpoint.

Authorizations:
Bearer
Request Body schema:
resetToken
required
string non-empty

Short-lived JWT issued after successful OTP verification for PIN reset.

newPin
required
string [ 4 .. 6 ] characters

The new 4–6 digit PIN to set on the user's account.

Responses

Request samples

Content type
{
  • "resetToken": "string",
  • "newPin": "string"
}

Response samples

Content type
No sample

Returns current user profile (requires Authorization: Bearer ...). Use query string to include extra sections: ?include=device,accounts,loans,repayments

Authorizations:
Bearer
query Parameters
include
string
loansPage
integer <int32>
Default: 1
loansPageSize
integer <int32>
Default: 10
scheduleLimit
integer <int32>
Default: 3

Responses

Response samples

Content type
No sample

LentMeBanks

Provides endpoints for creating, updating, and resolving banks. Write operations require admin/ops. Read endpoints are open.

Creates a single bank (admin/ops).

Authorizations:
Bearer
Request Body schema:

Bank to create.

id
integer <int32>

Gets or sets the primary key.

bankCode
required
string [ 1 .. 20 ] characters

Gets or sets the unique bank code used to identify the bank (e.g., SKYE01, ACC01).

bankName
required
string [ 1 .. 100 ] characters

Gets or sets the name of the bank (e.g., "Access Bank", "Skye Bank").

Responses

Request samples

Content type
{
  • "id": 0,
  • "bankCode": "string",
  • "bankName": "string"
}

Response samples

Content type
No sample

Creates banks in bulk, skipping any with existing codes (admin/ops).

Authorizations:
Bearer
Request Body schema:

List of banks to create.

Array
id
integer <int32>

Gets or sets the primary key.

bankCode
required
string [ 1 .. 20 ] characters

Gets or sets the unique bank code used to identify the bank (e.g., SKYE01, ACC01).

bankName
required
string [ 1 .. 100 ] characters

Gets or sets the name of the bank (e.g., "Access Bank", "Skye Bank").

Responses

Request samples

Content type
[
  • {
    }
]

Response samples

Content type
No sample

Updates an existing bank by ID (admin/ops).

Authorizations:
Bearer
path Parameters
id
required
integer <int32>

Bank ID.

Request Body schema:

Updated bank data.

id
integer <int32>

Gets or sets the primary key.

bankCode
required
string [ 1 .. 20 ] characters

Gets or sets the unique bank code used to identify the bank (e.g., SKYE01, ACC01).

bankName
required
string [ 1 .. 100 ] characters

Gets or sets the name of the bank (e.g., "Access Bank", "Skye Bank").

Responses

Request samples

Content type
{
  • "id": 0,
  • "bankCode": "string",
  • "bankName": "string"
}

Response samples

Content type
No sample

Retrieves all banks (public).

Authorizations:
Bearer

Responses

Retrieves a bank by its code (public).

Authorizations:
Bearer
path Parameters
code
required
string

Bank code.

Responses

Response samples

Content type
No sample

Resolves a bank from an account number (public).

Authorizations:
Bearer
path Parameters
accountNumber
required
string

Account number to inspect.

Responses

Response samples

Content type
No sample

LentMeBankVerification

Verifies OTPs for the bank account linking step. Requires an authenticated mobile user; the OTP is validated strictly against the caller's phone number from the JWT.

Verifies an OTP for the bank linking process. The phone number is taken from the authenticated JWT to prevent spoofing.

Authorizations:
Bearer
Request Body schema:

Contains the OTP code (the phone in this DTO is ignored).

phoneNumber
string or null

Gets or sets the phone number associated with the OTP.

code
string or null

Gets or sets the OTP code provided by the user for verification.

Responses

Request samples

Content type
{
  • "phoneNumber": "string",
  • "code": "string"
}

Response samples

Content type
No sample

LoanEvaluation

Evaluates loan eligibility for signed-in mobile users.

Evaluates a user's eligibility for a loan based on deposit history and configured rules.

Authorizations:
Bearer
Request Body schema:

Loan evaluation request DTO.

userId
required
string <uuid>

Unique identifier of the loan applicant (borrower public GUID).

requestedLoanAmount
required
number <double> >= 0.01

Requested loan amount by the applicant.

loanTerm
required
integer <int32> [ 1 .. 480 ]

Duration of the loan in months (e.g., 1, 3, 6, 12).

accountNumber
required
string [ 5 .. 64 ] characters

Applicant's bank account number used for deposit history analysis.

isReturningCustomer
boolean

Indicates whether the applicant is a returning customer.

previousLoanPaid
boolean or null

Indicates if the applicant previously repaid a loan (used for returning customers).

monthlyDeposits
Array of numbers or null <double> [ items <double > ]

Historical deposit amounts per month (used if external data not available).

Responses

Request samples

Content type
{
  • "userId": "2c4a230c-5085-4924-a3e1-25fb4fc5965b",
  • "requestedLoanAmount": 0.01,
  • "loanTerm": 1,
  • "accountNumber": "string",
  • "isReturningCustomer": true,
  • "previousLoanPaid": true,
  • "monthlyDeposits": [
    ]
}

Response samples

Content type
No sample

Loans

Provides endpoints for managing loan applications for authenticated mobile users.

Applies for a loan. The underlying service evaluates eligibility and, if approved, proceeds to disbursement and returns a repayment schedule.

Authorizations:
Bearer
Request Body schema:

Loan application details supplied by the client.

userId
string <uuid>

Borrower/user identifier.

accountNumber
string or null

Beneficiary account number (must be the user's linked bank account). The bank code will be resolved from the linkage; do not send it here.

amount
number <double>

Principal amount requested by the user.

loanTerm
integer <int32>

Loan term in months (e.g., 1, 3, or 6).

firstDueDateUtc
string or null <date-time>

Optional first due date (UTC). If null, schedule begins one month after disbursement.

Responses

Request samples

Content type
{
  • "userId": "2c4a230c-5085-4924-a3e1-25fb4fc5965b",
  • "accountNumber": "string",
  • "amount": 0.1,
  • "loanTerm": 0,
  • "firstDueDateUtc": "2019-08-24T14:15:22Z"
}

Response samples

Content type
No sample

Reconciliation

Reconciliation endpoints for operators: list/export unmatched legs, retry failed legs, and mark manual matches.

Lists unmatched successful legs within a UTC window, including suggested deposit matches.

Authorizations:
Bearer
query Parameters
fromUtc
string <date-time>

Start of window (UTC). Defaults to 30 days ago.

toUtc
string <date-time>

End of window (UTC). Defaults to now.

Responses

Response samples

Content type
No sample

Exports unmatched legs to a CSV for the given UTC window.

Authorizations:
Bearer
query Parameters
fromUtc
string <date-time>

Start of window (UTC). Defaults to 30 days ago.

toUtc
string <date-time>

End of window (UTC). Defaults to now.

Responses

Retries a failed or reversed payment leg by issuing a new funds transfer with a fresh document reference.

Authorizations:
Bearer
path Parameters
legId
required
string <uuid>

Identifier of the leg to retry.

Responses

Response samples

Content type
No sample

Marks a payment leg as matched to a specified deposit transaction (manual reconciliation).

Authorizations:
Bearer
path Parameters
legId
required
string <uuid>

Identifier of the leg to mark.

Request Body schema:

Request with deposit Id and optional note.

depositId
string <uuid>

Identifier of the deposit transaction chosen by an operator.

note
string or null

Optional operator note (reason/context).

Responses

Request samples

Content type
{
  • "depositId": "33504022-daeb-4ddf-96f2-fc15aa4e6a52",
  • "note": "string"
}

Reliability

API endpoints for retrieving and persisting borrower reliability scores.

Gets the reliability score for a borrower (computed on the fly).

Authorizations:
Bearer
path Parameters
userId
required
string <uuid>

Borrower identifier.

query Parameters
loanId
string <uuid>

Optional loan identifier.

Responses

Response samples

Content type
No sample

Computes and persists a new reliability score snapshot for a borrower. Typically invoked by an admin or scheduled job.

Authorizations:
Bearer
path Parameters
userId
required
string <uuid>

Borrower identifier.

query Parameters
loanId
string <uuid>

Optional loan identifier.

Responses

Response samples

Content type
No sample

Gets the most recent persisted reliability score snapshot for a borrower.

Authorizations:
Bearer
path Parameters
userId
required
string <uuid>

Borrower identifier.

Responses

Response samples

Content type
No sample

Surveys

Administrative endpoints for creating surveys, inviting waitlisted users, and collecting responses.

Create a new survey with questions.

Authorizations:
Bearer
Request Body schema:

Survey title, description, and questions/options.

title
string or null
description
string or null
Array of objects or null (SurveyQuestionDto)

Responses

Request samples

Content type
{
  • "title": "string",
  • "description": "string",
  • "questions": [
    ]
}

Response samples

Content type
No sample

Invite eligible waitlist entries to take the survey via SMS/email.

Authorizations:
Bearer
path Parameters
id
required
integer <int64>

Survey id.

Request Body schema:

Invitation preferences and filters.

surveyId
integer <int64>
channel
string or null
onlyVerified
boolean

Responses

Request samples

Content type
{
  • "surveyId": 0,
  • "channel": "string",
  • "onlyVerified": true
}

Response samples

Content type
No sample

Public endpoint to submit responses to a survey. Accepts an optional token from the invite link for tracking.

Authorizations:
Bearer
path Parameters
id
required
integer <int64>

Survey id.

query Parameters
t
string

Optional invite token provided in the link.

Request Body schema:

Answers keyed by QuestionId.

waitlistEntryId
integer <int64>
Array of objects or null (SurveyAnswerDto)

Responses

Request samples

Content type
{
  • "waitlistEntryId": 0,
  • "answers": [
    ]
}

Response samples

Content type
No sample

Get simple aggregate stats for a survey (counts, completion rate, etc.).

Authorizations:
Bearer
path Parameters
id
required
integer <int64>

Survey id.

Responses

Response samples

Content type
No sample

Export survey responses as CSV.

Authorizations:
Bearer
path Parameters
id
required
integer <int64>

Survey id.

Responses

Waitlist

Public endpoints to join and verify the LentMe waitlist. Mirrors LentMeUser fields for seamless conversion at launch.

Join the LentMe waitlist. Requires at least a valid phone number (or email per DTO rules).

Authorizations:
Bearer
Request Body schema:

Signup payload mirroring LentMeUser fields plus consent and source.

phoneNumber
string or null
firstName
string or null
lastName
string or null
gender
string or null
dateOfBirth
string <date-time>
address
string or null
consentMarketing
boolean

Explicit opt-in to receive communications.

source
string or null

Attribution source (optional).

Responses

Request samples

Content type
{
  • "phoneNumber": "string",
  • "firstName": "string",
  • "lastName": "string",
  • "gender": "string",
  • "dateOfBirth": "2019-08-24T14:15:22Z",
  • "address": "string",
  • "consentMarketing": true,
  • "source": "string"
}

Response samples

Content type
No sample

Get the current status of a waitlist entry via its public GUID.

Authorizations:
Bearer
path Parameters
publicId
required
string <uuid>

Public GUID for the waitlist entry.

Responses

Response samples

Content type
No sample

Send or resend the verification code via SMS/email to the waitlist entry by numeric ID.

Authorizations:
Bearer
path Parameters
waitlistEntryId
required
integer <int64>

Internal numeric ID of the waitlist entry.

Responses

Response samples

Content type
No sample

Verify a waitlist entry using a one-time code received via SMS/email.

Authorizations:
Bearer
Request Body schema:

PublicId or internal ID (per DTO) plus the OTP code.

waitlistEntryId
integer <int64>
code
string or null

Responses

Request samples

Content type
{
  • "waitlistEntryId": 0,
  • "code": "string"
}

Response samples

Content type
No sample

Unsubscribe a waitlist entry (by numeric ID) from marketing communications.

Authorizations:
Bearer
path Parameters
waitlistEntryId
required
integer <int64>

Internal numeric ID of the waitlist entry.

query Parameters
reason
string

Optional reason for unsubscribing.

Responses

Response samples

Content type
No sample

Unsubscribe a waitlist entry (by public GUID) from marketing communications.

Authorizations:
Bearer
path Parameters
publicId
required
string <uuid>

Public GUID for the waitlist entry.

query Parameters
reason
string

Optional reason for unsubscribing.

Responses

Response samples

Content type
No sample