9 endpoints · base URL https://flexysure.intrepidprojects.co.ke/api/v1
Spread a premium over monthly instalments with Flexysure Premium Finance: quote, apply, sign the agreement with a one-time code, collect the deposit and follow the loan. Offered through brokerages and agencies only: a SACCO or microfinance token gets 403 ipf_not_offered. Credit decisions and paying the underwriter stay with Flexysure Finance staff; there is no API to approve an application or disburse a loan. Instalments are paid to Flexysure Finance's paybill with the loan ref as the account number, or by an M-Pesa prompt: POST /payment/stk/push with the loan ref as account (purpose ipf_repayment). A running loan can be settled early with POST /ipf/loans/{uuid}/early-settlement. Rule failures from the finance actions come back as 422 validation_failed with the reason under errors.ipf (or errors.otp, errors.tenor_months).
One offer per repayment period the lender offers (deposit, financed amount, interest, fees, instalment, APR) and whether this policy can apply now. A policy must be saved with premium finance as its payment mode and be awaiting payment.
Scope
finance
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Submits the application to Flexysure Finance, who decide in their portal. Calling this confirms the client agreed to the terms and to sharing their details with the lender; the time is recorded as consent_at. The application is owned by the API client's actor user (or the user who created the client).
Scope
finance
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Required: send an Idempotency-Key; a retry with the same key replays the first response.
Headers
Header
Meaning
Authorization
Bearer <access_token> (scope finance)
Idempotency-Key
Required. A unique value (a UUID) per write. Replays within 24 hours return the stored response with Idempotent-Replayed: true; the same key with a different body is rejected (idempotency_key_reused).
Texts a 6-digit code to the client's phone for signing the approved agreement (charged to the SMS balance). sent is true only when the SMS was queued or sent; otherwise sent: false with reason. Each call replaces the previous code; it expires after expires_in seconds and allows 5 tries. Only a hash is stored. In the demo the code also comes back as demo_otp.
Scope
finance
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Required: send an Idempotency-Key; a retry with the same key replays the first response.
Headers
Header
Meaning
Authorization
Bearer <access_token> (scope finance)
Idempotency-Key
Required. A unique value (a UUID) per write. Replays within 24 hours return the stored response with Idempotent-Replayed: true; the same key with a different body is rejected (idempotency_key_reused).
{
"sent": true,
"message_status": "sent",
"phone": "0712 345 678",
"expires_in": 600,
"demo_otp": "483920",
"demo_note": "Demo mode: the code is returned here instead of being sent by SMS."
}
Responses
Status
Meaning
200
{sent: true}, or {sent: false, reason} when the SMS could not go
403
ipf_not_offered
404
Unknown application
422
Not approved yet (errors.ipf)
Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.
POST/api/v1/ipf/applications/{uuid}/signFlexysure only
Checks the code and books the loan in pending_deposit. The signature evidence is the sha256 of the agreement text, the caller's IP and the time. Next: collect the deposit with POST /ipf/loans/{uuid}/deposit.
Scope
finance
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Required: send an Idempotency-Key; a retry with the same key replays the first response.
Headers
Header
Meaning
Authorization
Bearer <access_token> (scope finance)
Idempotency-Key
Required. A unique value (a UUID) per write. Replays within 24 hours return the stored response with Idempotent-Replayed: true; the same key with a different body is rejected (idempotency_key_reused).
Parameters
Name
In
Type
Required
Description
uuid
path
string
Yes
Application uuid.
Body fields
Field
Type
Required
Description
otp
string
Yes
The 6-digit code the client received.
Example: 483920
Terms, repayment schedule, what has been repaid (split fees, then interest, then principal inside each instalment), what is outstanding, arrears and how many days the oldest missed instalment is late. The schedule appears once Flexysure Finance has paid the underwriter.
Scope
finance
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Sends an STK push for the deposit (purpose ipf_deposit). When the customer pays, the receipt is allocated to the policy's debit note and the loan moves to pending_disbursement; cover starts after Flexysure Finance pays the underwriter. Poll with GET /payment/stk/{uuid}.
Scope
finance
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Required: send an Idempotency-Key; a retry with the same key replays the first response.
Headers
Header
Meaning
Authorization
Bearer <access_token> (scope finance)
Idempotency-Key
Required. A unique value (a UUID) per write. Replays within 24 hours return the stored response with Idempotent-Replayed: true; the same key with a different body is rejected (idempotency_key_reused).
With ?quote=1: the payoff figure for today and nothing else. Without it: the same quote plus an STK push for the payoff amount (phone required). Payoff rule: unpaid principal on every instalment, plus unpaid interest and fees on instalments already due (due date on or before today), plus interest on the current instalment accrued pro rata by days from the previous due date (or one month before the first) to today. Interest and fees on later instalments are waived. Rounded up to the shilling, never more than the contractual outstanding balance, valid today only. Use a new Idempotency-Key for each quote. When the customer pays the prompt (purpose ipf_settlement), the payoff is recomputed for the payment date: paying at least that much closes the loan (statusclosed), the remaining interest and fees are waived (schedule lines waived), anything above the payoff is kept as a borrower credit, and the loan timeline shows "Settled early". Paying less than the payoff counts as an ordinary instalment and the loan stays open. Poll GET /payment/stk/{uuid} and GET /ipf/loans/{uuid}.
Scope
finance
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Required: send an Idempotency-Key; a retry with the same key replays the first response.
Headers
Header
Meaning
Authorization
Bearer <access_token> (scope finance)
Idempotency-Key
Required. A unique value (a UUID) per write. Replays within 24 hours return the stored response with Idempotent-Replayed: true; the same key with a different body is rejected (idempotency_key_reused).
Parameters
Name
In
Type
Required
Description
uuid
path
string
Yes
Loan uuid.
quote
query
boolean
No
1 to get the payoff figure without sending a prompt.
Body fields
Field
Type
Required
Description
phone
string
No
Required unless quote=1. 07XXXXXXXX or 2547XXXXXXXX.
Example: 0712345678
{
"data": {
"loan_ref": "IPF-000017",
"as_of": "2026-12-01",
"payoff": 34200,
"payoff_minor": 3420000,
"principal": 33334,
"principal_minor": 3333400,
"interest_accrued": 866,
"interest_accrued_minor": 86600,
"fees_due": 0,
"fees_due_minor": 0,
"outstanding": 38750,
"outstanding_minor": 3875000,
"waived": 4550,
"waived_minor": 455000,
"rule": "Unpaid principal + interest and fees on instalments already due + interest accrued pro rata on the current instalment to today; later interest and fees are waived. Valid today only."
}
}
Responses
Status
Meaning
200
Quote (data), and stk when a prompt was sent
403
ipf_not_offered
404
Unknown loan
422
not_settleable (loan not running), validation_failed (phone missing without quote=1) or payment_refused. No money moved.
Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.