Skip to content
Demo environment. M-Pesa and DMVIC are simulated; no real money or certificates move. Sandbox details
FlexySure

Client area

19 endpoints · base URL https://flexysure.intrepidprojects.co.ke/api/v1

A customer's own account for your app or website, compatible with Insurance Cloud's Client Area: passwordless sign-in by one-time code, details, policies, policy detail with documents and a ledger-backed statement. Sign-in returns client_no and client_key; send them as X-Client-No and X-Client-Key with your organisation's bearer token. Money in the Insurance Cloud endpoints is in shillings; the Flexysure-only endpoints (loans, pay, claims) use integer cents (*_minor). Policy status is 1 for active cover and 0 for any other status. A new sign-in (verify-otp or register) replaces the client's earlier keys; the key returned when your system saves a policy (portal.client_key) replaces only earlier policy keys, so it never signs the customer out of their app.

MethodPathSummaryScope
POST /api/v1/client/login Request a sign-in code —
POST /api/v1/client/verify-otp Verify the code and get the client key —
POST /api/v1/client/logout Sign out (revoke the client key) —
POST /api/v1/client/register Register a client with its own login portal
GET /api/v1/client/details Client details and documents portal
POST /api/v1/client/policies List the client's policies portal
POST /api/v1/client/policies/all List all the client's policies (no pagination) portal
GET /api/v1/client/policy/{id} Policy detail portal
POST /api/v1/client/statement Statement of account portal
GET /api/v1/client/loans Premium-finance loans Flexysure only portal
GET /api/v1/client/loans/{uuid} Premium-finance loan with schedule Flexysure only portal
POST /api/v1/client/policy/{id}/pay Pay a policy by M-Pesa Flexysure only portal
GET /api/v1/client/claims The client's claims Flexysure only portal
POST /api/v1/client/claims Lodge a claim Flexysure only portal
GET /api/v1/client/files/kyc/{uuid} Client document (signed link) —
GET /api/v1/client/files/policies/{policy}/risk-note Risk note PDF (signed link) —
GET /api/v1/client/files/debit-notes/{note} Invoice or credit note PDF (signed link) —
GET /api/v1/client/files/receipts/{receipt} Receipt PDF (signed link) —
GET /api/v1/client/files/certificates/{certificate} Motor certificate PDF (signed link) —
POST /api/v1/client/login

Request a sign-in code

Send the email or phone saved on the client record (or its login). If both are sent both must match the same account. The same six-digit code goes by SMS and email and expires after 5 minutes. No bearer token is needed; when the same contact is a client of more than one organisation, send the organisation's bearer token to choose. The answer never reveals whether an account exists: unknown, disabled or (without a token) ambiguous contacts get the same 200 body, and channels is always ["email", "sms"], but no code is sent and the otp_id never verifies.

Scope
None
Authentication
None (client credentials in the body)
Rate limit
3 codes per 5 minutes per identifier and per account
Idempotency
Not keyed. Check before retrying.

Headers

HeaderMeaning
Acceptapplication/json
Content-Typeapplication/json
AuthorizationOptional. Bearer token of the organisation, to pick the account when the contact exists at several.

Body fields

FieldTypeRequiredDescription
email string No Saved email (max 255). Required without phone. Example: jane@example.com
phone string No Saved phone (max 50). Required without email. Example: 0712345678

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/client/login' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "jane@example.com"
}'
Request body (JSON)
Request body JSON
{
    "email": "jane@example.com"
}
Response JSON
{
    "status": "success",
    "message": "OTP sent successfully",
    "otp_id": "9b1f…",
    "expires_in": 300,
    "channels": [
        "email",
        "sms"
    ]
}

Responses

StatusMeaning
200 Code sent (the same body for contacts that cannot sign in)
403 Insecure request (https_required)
409 With a bearer token: the contact is on several clients of that organisation (ambiguous_client)
422 Invalid input
429 More than 3 codes in 5 minutes for this identifier or account

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

POST /api/v1/client/verify-otp

Verify the code and get the client key

Consumes the code and returns the user with client_no and a new client_key, which replaces any earlier key. Five wrong codes exhaust the request; ask for a new code.

Scope
None
Authentication
None (client credentials in the body)
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Not keyed. Check before retrying.

Headers

HeaderMeaning
Acceptapplication/json
Content-Typeapplication/json

Body fields

FieldTypeRequiredDescription
otp_id string Yes UUID from login.
otp string Yes The six-digit code. Example: 123456

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/client/verify-otp' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "otp_id": "9b1f…",
    "otp": "123456"
}'
Request body (JSON)
Request body JSON
{
    "otp_id": "9b1f…",
    "otp": "123456"
}
Response JSON
{
    "status": "success",
    "message": "Login successful",
    "user": {
        "name": "Jane Doe",
        "email": "jane@example.com",
        "phone": "0712345678",
        "department_id": null,
        "department": null,
        "company": null,
        "client_no": "C-00042",
        "national_id": "12345678",
        "kra_pin": "A012345678Z",
        "client_key": "fxck_…",
        "is_admin": true,
        "risk_manager_id": 2
    }
}

Responses

StatusMeaning
200 Signed in
403 Locked or disabled account; insecure request
422 Wrong, expired or used code (invalid_otp, with attempts_left)
429 Attempts exhausted (otp_attempts_exhausted)

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

POST /api/v1/client/logout

Sign out (revoke the client key)

Scope
None
Authentication
None (client credentials in the body)
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Not keyed. Check before retrying.

Headers

HeaderMeaning
Acceptapplication/json
Content-Typeapplication/json

Body fields

FieldTypeRequiredDescription
client_no string Yes Client number.
client_key string Yes The key to revoke.

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/client/logout' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "client_no": "C-00042",
    "client_key": "fxck_…"
}'
Request body (JSON)
Request body JSON
{
    "client_no": "C-00042",
    "client_key": "fxck_…"
}
Response JSON
{
    "status": "success",
    "message": "Logout successful"
}

Responses

StatusMeaning
200 Signed out
403 Insecure request
422 Invalid input, or invalid or already revoked key (invalid_client_credentials)

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

POST /api/v1/client/register

Register a client with its own login

Creates an individual or corporate client in the token's organisation, a customer login for the contact and a client key. For a corporate client the company is the client and the contact is its login. An existing login with that email, or a client with that ID number or KRA PIN, returns 403: sign in by code instead.

Scope
portal
Authentication
Bearer token
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Not keyed. Check before retrying.

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
Acceptapplication/json
Content-Typeapplication/json

Body fields

FieldTypeRequiredDescription
type string Yes Client type. One of: individual, corporate
company object No Required for corporate.
company.name string Yes Max 255.
company.phone string Yes Max 50.
company.email string Yes Max 255.
company.kra_pin string Yes Max 50.
contact object Yes The person who signs in.
contact.name string Yes Max 255.
contact.phone string Yes Max 50.
contact.email string Yes Max 255; becomes the login.
contact.id_no string No Required for individual. Max 50.
contact.kra_pin string No Optional. Max 50.
contact.password string Yes At least 8 characters (for the web customer portal).

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/client/register' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "individual",
    "contact": {
        "name": "Jane Doe",
        "phone": "0712345678",
        "email": "jane@example.com",
        "id_no": "12345678",
        "password": "secret123"
    }
}'
Request body (JSON)
Request body JSON
{
    "type": "individual",
    "contact": {
        "name": "Jane Doe",
        "phone": "0712345678",
        "email": "jane@example.com",
        "id_no": "12345678",
        "password": "secret123"
    }
}
Response JSON
{
    "status": "success",
    "client": {
        "id": 42,
        "client_no": "C-00042",
        "client_name": "Jane Doe"
    },
    "user": {
        "name": "Jane Doe",
        "email": "jane@example.com",
        "phone": "0712345678",
        "department_id": null,
        "department": null,
        "company": null,
        "client_no": "C-00042",
        "national_id": "12345678",
        "kra_pin": "A012345678Z",
        "client_key": "fxck_…",
        "is_admin": true,
        "risk_manager_id": 2
    }
}

Responses

StatusMeaning
201 Client, login and key created
403 Account already exists (account_exists); insecure request
422 Invalid input

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/details

Client details and documents

Scope
portal
Authentication
Bearer token plus client-area headers
Rate limit
5 requests per minute per client (per client and policy on the detail)
Idempotency
Safe to repeat (read only).

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/details' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY"
Response JSON
{
    "status": "success",
    "client": {
        "id": 42,
        "client_no": "C-00042",
        "client_name": "Jane Doe",
        "email": "jane@example.com",
        "mobile": "0712345678",
        "pin": "A012345678Z",
        "national_id": "12345678"
    },
    "client_documents": [
        {
            "id": "5d0c…",
            "name": "National ID",
            "url": "https://…/api/v1/client/files/kyc/5d0c…?expires=…&signature=…",
            "download_url": "https://…&download=1…"
        }
    ]
}

Responses

StatusMeaning
200 Client and KYC documents
400 Insecure (non-HTTPS) request (https_required)
401 Missing or invalid bearer token
422 Invalid input, or invalid_client_credentials (unknown, revoked or other-organisation client key)

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

POST /api/v1/client/policies

List the client's policies

Paginated. Later pages are POSTed to the same URL with the same filters and page (the links are not GET endpoints).

Scope
portal
Authentication
Bearer token plus client-area headers
Rate limit
5 requests per minute per client (per client and policy on the detail)
Idempotency
Not keyed. Check before retrying.

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
Acceptapplication/json
Content-Typeapplication/json
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.

Body fields

FieldTypeRequiredDescription
status integer Yes 1 active, 0 any other status, 2 all. One of: 0, 1, 2
insurer_id integer No One underwriter.
product_id integer No One standard product; takes precedence over exclude_product_ids.
exclude_product_ids integer[] No Products to leave out.
starting string No Y-m-d. With ending: policies starting in the window.
ending string No Y-m-d, on or after starting.
page integer No Default 1.
per_page integer No 1–100, default 15.

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/client/policies' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "status": 2,
    "page": 1,
    "per_page": 15
}'
Request body (JSON)
Request body JSON
{
    "status": 2,
    "page": 1,
    "per_page": 15
}
Response JSON
{
    "status": "success",
    "policies": [
        {
            "id": 125,
            "status": 1,
            "transaction": "New Business",
            "policy_no": "POL-001",
            "product_id": null,
            "insurer": "Savanna General",
            "client": "Jane Doe",
            "product": "MOTOR",
            "sub_cover": "Comprehensive",
            "currency": "KES",
            "start_date": "2026-09-01",
            "end_date": "2027-08-31",
            "sales_type": "Cash",
            "risk_note": "RN-00001",
            "sum_insured": 1000000,
            "premium": 50000,
            "receipted": 20000,
            "balance": 30000
        }
    ],
    "meta": {
        "current_page": 1,
        "last_page": 1,
        "per_page": 15,
        "total": 1
    },
    "links": {
        "first": "https://…/api/v1/client/policies?page=1",
        "prev": null,
        "next": null,
        "last": "https://…/api/v1/client/policies?page=1"
    }
}

Responses

StatusMeaning
200 Policies with meta and links
400 Insecure (non-HTTPS) request (https_required)
401 Missing or invalid bearer token
422 Invalid input, or invalid_client_credentials (unknown, revoked or other-organisation client key)

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

POST /api/v1/client/policies/all

List all the client's policies (no pagination)

Same filters as the paginated list, without page and per_page. At most 500 policies, newest first; truncated is true when there were more (page through POST /client/policies instead).

Scope
portal
Authentication
Bearer token plus client-area headers
Rate limit
5 requests per minute per client (per client and policy on the detail)
Idempotency
Not keyed. Check before retrying.

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
Acceptapplication/json
Content-Typeapplication/json
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.

Body fields

FieldTypeRequiredDescription
status integer Yes 1 active, 0 any other status, 2 all. One of: 0, 1, 2
insurer_id integer No One underwriter.
product_id integer No One standard product.
exclude_product_ids integer[] No Products to leave out.
starting string No Y-m-d.
ending string No Y-m-d.

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/client/policies/all' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "status": 1
}'
Request body (JSON)
Request body JSON
{
    "status": 1
}
Response JSON
{
    "status": "success",
    "policies": [
        {
            "id": 125,
            "status": 1,
            "transaction": "New Business",
            "policy_no": "POL-001",
            "product_id": null,
            "insurer": "Savanna General",
            "client": "Jane Doe",
            "product": "MOTOR",
            "sub_cover": "Comprehensive",
            "currency": "KES",
            "start_date": "2026-09-01",
            "end_date": "2027-08-31",
            "sales_type": "Cash",
            "risk_note": "RN-00001",
            "sum_insured": 1000000,
            "premium": 50000,
            "receipted": 20000,
            "balance": 30000
        }
    ],
    "truncated": false
}

Responses

StatusMeaning
200 Policies
400 Insecure (non-HTTPS) request (https_required)
401 Missing or invalid bearer token
422 Invalid input, or invalid_client_credentials (unknown, revoked or other-organisation client key)

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/policy/{id}

Policy detail

Totals, receipt allocations (with receipt PDFs), vehicles, claims, documents (risk note, invoices, motor certificates) and the client's KYC documents. Document links are temporary signed URLs valid for 30 minutes. marine_dmvic is always null (Flexysure has no marine line).

Scope
portal
Authentication
Bearer token plus client-area headers
Rate limit
5 requests per minute per client (per client and policy on the detail)
Idempotency
Safe to repeat (read only).

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.

Parameters

NameInTypeRequiredDescription
id path integer Yes Policy id from the policies list. Example: 125

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/policy/125' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY"
Response JSON
{
    "status": "success",
    "policy": {
        "id": 125,
        "status": 1,
        "transaction": "New Business",
        "policy_no": "POL-001",
        "product_id": null,
        "insurer": "Savanna General",
        "client": "Jane Doe",
        "product": "MOTOR",
        "sub_cover": "Comprehensive",
        "currency": "KES",
        "start_date": "2026-09-01",
        "end_date": "2027-08-31",
        "sales_type": "Cash",
        "risk_note": "RN-00001",
        "sum_insured": 1000000,
        "premium": 50000,
        "receipted": 20000,
        "balance": 30000,
        "marine_dmvic": null,
        "risk_note_link": "https://…/risk-note?expires=…&signature=…",
        "invoice_link": "https://…/debit-notes/77?expires=…",
        "receipt_allocations": [
            {
                "amount": 20000,
                "reference": "RCT-00012",
                "auth_date": "2026-09-01 10:02:11",
                "receipt_url": "https://…/receipts/12?expires=…"
            }
        ],
        "vehicles": [
            {
                "id": 9,
                "reg_no": "KDA 123A",
                "make": "Toyota",
                "model": "Axio",
                "year": 2018,
                "chassis_no": "NZE161-…",
                "engine_no": "1NZ-…",
                "body_type": "Saloon",
                "value": 1000000
            }
        ],
        "claims": [],
        "policy_documents": [
            {
                "id": "risk-note-125",
                "name": "Risk note RN-00001",
                "source": "system",
                "url": "https://…"
            }
        ],
        "client_documents": []
    }
}

Responses

StatusMeaning
200 Policy
404 Not this client's policy (unknown ids and other clients' or organisations' policies answer the same)
422 An id that is not a number, or invalid client credentials
400 Insecure (non-HTTPS) request (https_required)
401 Missing or invalid bearer token

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

POST /api/v1/client/statement

Statement of account

Read from the ledger (client receivables): billed amounts are debits; receipts, premium-finance funding and credit notes are credits. The first row is the opening balance; each row carries the running balance; zero debit or credit cells are empty strings. A statement covers at most 366 days (422 range_too_long).

Scope
portal
Authentication
Bearer token plus client-area headers
Rate limit
10 requests per minute per client
Idempotency
Not keyed. Check before retrying.

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
Acceptapplication/json
Content-Typeapplication/json
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.

Body fields

FieldTypeRequiredDescription
starting string Yes Y-m-d. Example: 2026-01-01
ending string Yes Y-m-d, on or after starting, at most 366 days in all. Example: 2026-12-31

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/client/statement' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "starting": "2026-01-01",
    "ending": "2026-12-31"
}'
Request body (JSON)
Request body JSON
{
    "starting": "2026-01-01",
    "ending": "2026-12-31"
}
Response JSON
{
    "status": "success",
    "client": "Jane Doe",
    "client_no": "C-00042",
    "starting": "2026-01-01",
    "ending": "2026-12-31",
    "opening_balance": 0,
    "closing_balance": 30000,
    "total_debit": 50000,
    "total_credit": 20000,
    "statement": [
        {
            "date": "2026-01-01",
            "reference": "",
            "insurer_ref": "",
            "transaction": "",
            "insurer": "",
            "policy_no": "",
            "narration": "Opening Balance",
            "dr": "",
            "cr": "",
            "balance": 0
        },
        {
            "date": "2026-09-01",
            "reference": "DN-00077",
            "insurer_ref": "",
            "transaction": "Debit note",
            "insurer": "Savanna General",
            "policy_no": "POL-001",
            "narration": "Debit note raised DN-00077 for POL-001",
            "dr": 50000,
            "cr": "",
            "balance": 50000
        },
        {
            "date": "2026-09-01",
            "reference": "RCT-00012",
            "insurer_ref": "",
            "transaction": "Receipt",
            "insurer": "Savanna General",
            "policy_no": "POL-001",
            "narration": "Receipt RCT-00012 allocated to DN-00077",
            "dr": "",
            "cr": 20000,
            "balance": 30000
        }
    ]
}

Responses

StatusMeaning
200 Statement
400 Insecure (non-HTTPS) request (https_required)
401 Missing or invalid bearer token
422 Invalid input, or invalid_client_credentials (unknown, revoked or other-organisation client key)

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/loans Flexysure only

Premium-finance loans

Scope
portal
Authentication
Bearer token plus client-area headers
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/loans' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY"
Response JSON
{
    "data": [
        {
            "uuid": "1c2d…",
            "loan_ref": "IPF-00003",
            "status": "active",
            "status_label": "Active",
            "policy_id": 125,
            "policy_no": "POL-001",
            "lender": "Flexysure Premium Finance",
            "currency": "KES",
            "principal_minor": 4000000,
            "total_repayable_minor": 4650000,
            "repaid_minor": 775000,
            "balance_minor": 3875000,
            "arrears_minor": 0,
            "tenor_months": 6,
            "next_due": {
                "date": "2026-11-14",
                "amount_minor": 775000
            }
        }
    ]
}

Responses

StatusMeaning
200 Loans
400 Insecure (non-HTTPS) request (https_required)
401 Missing or invalid bearer token
422 Invalid input, or invalid_client_credentials (unknown, revoked or other-organisation client key)

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/loans/{uuid} Flexysure only

Premium-finance loan with schedule

Scope
portal
Authentication
Bearer token plus client-area headers
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.

Parameters

NameInTypeRequiredDescription
uuid path string Yes Loan uuid.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/loans/{uuid}' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY"
Response JSON
{
    "data": {
        "uuid": "1c2d…",
        "loan_ref": "IPF-00003",
        "balance_minor": 3875000,
        "schedule": [
            {
                "seq": 1,
                "due_on": "2026-11-14",
                "amount_due_minor": 775000,
                "amount_paid_minor": 0,
                "status": "due"
            }
        ],
        "repayments": []
    }
}

Responses

StatusMeaning
200 Loan, schedule and repayments
404 Not this client's loan
400 Insecure (non-HTTPS) request (https_required)
401 Missing or invalid bearer token
422 Invalid input, or invalid_client_credentials (unknown, revoked or other-organisation client key)

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

POST /api/v1/client/policy/{id}/pay Flexysure only

Pay a policy by M-Pesa

Sends an STK push for the earliest open debit note of the policy (for a premium-finance policy awaiting its deposit, the deposit). amount is in shillings and defaults to what is outstanding on that note. The payment is confirmed by the M-Pesa callback; watch the policy or the payment.* webhooks.

Scope
portal
Authentication
Bearer token plus client-area headers
Rate limit
5 requests per minute per client (per client and policy on the detail)
Idempotency
Required: send an Idempotency-Key; a retry with the same key replays the first response.

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
Acceptapplication/json
Content-Typeapplication/json
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.
Idempotency-KeyRequired. 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

NameInTypeRequiredDescription
id path integer Yes Policy id.

Body fields

FieldTypeRequiredDescription
phone string Yes Safaricom number to prompt. Example: 0712345678
amount number No Shillings; at most the outstanding amount.

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/client/policy/{id}/pay' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY" \
  -H 'Idempotency-Key: 80cf7aed-fbf3-48f9-a1d1-6b289bd2d96e' \
  -H 'Content-Type: application/json' \
  -d '{
    "phone": "0712345678"
}'
Request body (JSON)
Request body JSON
{
    "phone": "0712345678"
}
Response JSON
{
    "data": {
        "stk_request_id": 31,
        "merchant_request_id": "29115-…",
        "checkout_request_id": "ws_CO_…",
        "purpose": "premium",
        "account": "DN-00077",
        "phone": "254712345678",
        "amount_minor": 3000000,
        "status": "pending",
        "message": "Check your phone and enter your M-Pesa PIN to pay."
    }
}

Responses

StatusMeaning
202 Prompt sent
404 Not this client's policy (or no such policy)
422 Nothing to pay, amount too high, invalid phone, or an id that is not a number
401 Missing or invalid bearer token

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/claims Flexysure only

The client's claims

Cursor pagination (limit, cursor) or page / per_page.

Scope
portal
Authentication
Bearer token plus client-area headers
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Headers

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.

Parameters

NameInTypeRequiredDescription
limit query integer No 1–100, default 25.
cursor query string No From links.next.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/claims' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY"
Response JSON
{
    "data": [
        {
            "id": "7a1e…",
            "claim_no": "CLM/2026/00004",
            "policy_id": 125,
            "policy_no": "POL-001",
            "status": "registered",
            "status_label": "Registered",
            "type": "Accidental damage",
            "legal": "Non Legal",
            "item": "KDA 123A",
            "incident_date": "2026-10-01",
            "estimate": 80000,
            "narration": "Rear-ended at a junction."
        }
    ],
    "meta": {
        "limit": 25,
        "has_more": false,
        "count": 1
    },
    "links": {
        "next": null
    }
}

Responses

StatusMeaning
200 Claims
400 Insecure (non-HTTPS) request (https_required)
401 Missing or invalid bearer token
422 Invalid input, or invalid_client_credentials (unknown, revoked or other-organisation client key)

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

POST /api/v1/client/claims Flexysure only

Lodge a claim

Registers a claim on one of the client's policies (active, expired or cancelled; the incident must fall inside the cover period). The broker's claims team takes it from there.

Scope
portal
Authentication
Bearer token plus client-area headers
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

HeaderMeaning
AuthorizationBearer <access_token> (scope portal)
Acceptapplication/json
Content-Typeapplication/json
X-Client-NoRequired. user.client_no from verify-otp (or client.client_no from register).
X-Client-KeyRequired. user.client_key (fxck_…) from verify-otp or register. A new sign-in replaces the key.
Idempotency-KeyRequired. 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).

Body fields

FieldTypeRequiredDescription
policy_id integer Yes Policy id.
claim_type string Yes Kind of loss. One of: accidental_damage, theft, third_party, medical, travel, death, disability, other
incident_on string Yes Y-m-d, inside the cover period, not in the future.
description string Yes What happened.
risk_item string No Defaults to the vehicle registration on motor policies.
claimant_name string No Defaults to the client.
claimant_phone string No Defaults to the client's phone.
claimant_relationship string No self, driver, spouse, relative, employee, third_party…
estimate number No Estimated loss in shillings.

Example

Request cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/client/claims' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H "X-Client-No: $CLIENT_NO" \
  -H "X-Client-Key: $CLIENT_KEY" \
  -H 'Idempotency-Key: e20b1d7a-8960-479e-a585-3e02fa8b18b3' \
  -H 'Content-Type: application/json' \
  -d '{
    "policy_id": 125,
    "claim_type": "accidental_damage",
    "incident_on": "2026-10-01",
    "description": "Rear-ended at a junction.",
    "estimate": 80000
}'
Request body (JSON)
Request body JSON
{
    "policy_id": 125,
    "claim_type": "accidental_damage",
    "incident_on": "2026-10-01",
    "description": "Rear-ended at a junction.",
    "estimate": 80000
}
Response JSON
{
    "data": {
        "id": "7a1e…",
        "claim_no": "CLM/2026/00004",
        "status": "registered"
    }
}

Responses

StatusMeaning
201 Claim registered
404 Not this client's policy
422 Invalid input or a claims rule (domain_rule)
401 Missing or invalid bearer token

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/files/kyc/{uuid}

Client document (signed link)

Temporary signed URL (30 minutes). No headers needed; an expired or altered link returns 403. Add download=1 (already part of download_url) to download instead of viewing.

Scope
None
Authentication
None (client credentials in the body)
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Parameters

NameInTypeRequiredDescription
uuid path string Yes Document id.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/files/kyc/{uuid}' \
  -H 'Accept: application/json'

Responses

StatusMeaning
200 The file
403 Expired or invalid signature
404 Not found

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/files/policies/{policy}/risk-note

Risk note PDF (signed link)

Temporary signed URL (30 minutes). No headers needed; an expired or altered link returns 403.

Scope
None
Authentication
None (client credentials in the body)
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Parameters

NameInTypeRequiredDescription
policy path string Yes Policy uuid.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/files/policies/{policy}/risk-note' \
  -H 'Accept: application/json'

Responses

StatusMeaning
200 PDF
403 Expired or invalid signature
404 Not found

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/files/debit-notes/{note}

Invoice or credit note PDF (signed link)

Temporary signed URL (30 minutes). No headers needed; an expired or altered link returns 403.

Scope
None
Authentication
None (client credentials in the body)
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Parameters

NameInTypeRequiredDescription
note path integer Yes Debit note id.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/files/debit-notes/{note}' \
  -H 'Accept: application/json'

Responses

StatusMeaning
200 PDF
403 Expired or invalid signature
404 Not found

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/files/receipts/{receipt}

Receipt PDF (signed link)

Temporary signed URL (30 minutes). No headers needed; an expired or altered link returns 403.

Scope
None
Authentication
None (client credentials in the body)
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Parameters

NameInTypeRequiredDescription
receipt path integer Yes Receipt id.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/files/receipts/{receipt}' \
  -H 'Accept: application/json'

Responses

StatusMeaning
200 PDF
403 Expired or invalid signature
404 Not found

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.

GET /api/v1/client/files/certificates/{certificate}

Motor certificate PDF (signed link)

Temporary signed URL (30 minutes). No headers needed; an expired or altered link returns 403.

Scope
None
Authentication
None (client credentials in the body)
Rate limit
60 requests per minute per token (per-client override)
Idempotency
Safe to repeat (read only).

Parameters

NameInTypeRequiredDescription
certificate path integer Yes Certificate id.

Example

Request cURL
curl -X GET 'https://flexysure.intrepidprojects.co.ke/api/v1/client/files/certificates/{certificate}' \
  -H 'Accept: application/json'

Responses

StatusMeaning
200 PDF
403 Expired or invalid signature
404 Not found

Errors are problem documents; the common codes (401, 403 insufficient_scope, 422, 429) apply to every endpoint.