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

Flexysure Open API

Quote, bind, collect by M-Pesa, issue DMVIC certificates, finance premiums and receive signed webhooks from your own systems.

The Open API is how agency portals, core banking systems, comparison sites and ERPs work with an organisation on Flexysure. Everything a broker does on screen has an endpoint: price a risk across underwriters, save the quote as a policy, send an M-Pesa prompt, issue the motor certificate, offer premium finance, log a prospect or a claim, send an SMS, and give customers their own client area.

Requests and responses are JSON over HTTPS. Money is sent in whole shillings (amount) and returned in shillings plus integer cents (amount_minor). Every response carries an X-Request-Id header; quote it when you contact us.

Base URL

https://flexysure.intrepidprojects.co.ke/api/v1

Version

v1

Endpoints

97

Endpoint groups

Authentication 1 Flexysure issues short-lived bearer tokens to API clients created on Settings → API keys. Request a token with the OAuth2 client-credentials grant, th... Reference data 8 Look-ups you need before quoting or saving: the organisation's insurers, branches, staff, levies, motor benefits and product lines. All lists are scop... Motor 3 Price, quote and bind motor cover with Insurance Cloud field names. Amounts in requests are whole shillings; responses show whole shillings next to _m... Medical 4 Family medical cover with Insurance Cloud field names. Limits and premiums in requests are whole shillings. On save the family is re-priced from the m... Travel 2 Single-trip travel cover with Insurance Cloud field names, including its spellings (traveling_from, benefitiary_relationship, benefitiary_phone_no) —... Standard products 3 Packaged covers — personal accident, domestic package, WIBA, fire, golfer's and the like — priced flat, by age band or as a rate on the sum insured. I... Policies and quotes 7 Everything after the sale, which Insurance Cloud does not expose: list and read policies, endorse them mid-term, preview and confirm a cancellation wi... Payments 5 Collect premiums with an M-Pesa STK push, follow the prompt to its result, and read receipts and client balances. The STK callback lands on Flexysure'... Prospects 6 The CRM pipeline. Creating a prospect takes Insurance Cloud's field names (p_name, status, products[], assign_to[]) and answers in its shape; listing,... Clients 4 Policyholders, keyed by client number. Creating a client runs the same duplicate check as the web app (phone, ID number, KRA PIN): a match answers 409... Claims 5 Register claims on policies and move them through the lifecycle: registered → documents pending → with underwriter → under assessment → approved or re... Premium finance 9 Spread a premium over monthly instalments with Flexysure Premium Finance: quote, apply, sign the agreement with a one-time code, collect the deposit a... ERP exports 3 Insurance Cloud's ERP endpoints, record for record, for integrators syncing an accounting or ERP system: {status, <records>[], meta, links} with page/... Client area 19 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, polic... Motor certificates (DMVIC) 7 Issue, fetch, check and cancel DMVIC motor insurance certificates. Issuance follows the paid-stage rule: a policy is certified once it is active (firs... SMS 4 Send SMS from the organisation's sender ID and read the outbox, in Insurance Cloud's shapes. Each message costs one unit per 160-character segment fro... Webhooks 7 Register HTTPS endpoints and Flexysure will POST a signed JSON event to them when money lands, cover changes, a motor certificate is issued, a claim m...

Versioning

The version is in the path: /api/v1. Changes within v1 are additive: new endpoints, new optional request fields, new response fields and new webhook events, so build your client to ignore fields it does not know. A change that would break an integration would ship under a new version path. Every release is listed on the changelog.

Authentication

An administrator creates an API client on Settings → API keys, chooses its scopes and copies the secret, which is shown once. Your system exchanges the client id and secret for a bearer token with the OAuth2 client-credentials grant, then sends the token on every call. Tokens last 24 hours; request a new one when a call returns 401.

  1. 1. Get a token

    POST /oauth/token cURL
    curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/oauth/token' \
      -H 'Content-Type: application/json' \
      -d '{
        "grant_type": "client_credentials",
        "client_id": "<your client_id>",
        "client_secret": "<your client_secret>",
        "scope": "read quote bind pay"
      }'
    Response JSON
    {
        "access_token": "e3mT…48 characters…",
        "token_type": "Bearer",
        "expires_in": 86400,
        "scope": "read quote bind pay"
    }
  2. 2. Call the API with it

    GET /insurers cURL
    curl 'https://flexysure.intrepidprojects.co.ke/api/v1/insurers' \
      -H "Authorization: Bearer $ACCESS_TOKEN" \
      -H 'Accept: application/json'

The token endpoint also accepts a form body, HTTP Basic client authentication, and the body {"key": "…", "passkey": "…"} for systems moving from Insurance Cloud. It allows 10 attempts a minute per IP address. See Authentication for every response.

Scopes

A client is allowed a set of scopes; a token carries all of them or the subset you ask for in scope. * grants every scope. A call outside the token's scopes returns 403 insufficient_scope.

ScopeGrantsEndpoints
read Read reference data, policies, receipts and other records 23
quote Price motor, medical, travel and standard products 6
bind Save quotes and issue policies 7
pay Start M-Pesa payments and read payment status 5
certificate Issue, fetch and cancel DMVIC motor certificates 7
finance Premium finance: offers, applications, loans and repayments 9
crm Prospects and clients 6
claims Register and track claims 3
messaging Send SMS and read the outbox 4
portal Client area on behalf of a customer 11
webhooks Register webhook endpoints and read deliveries 7

Idempotency

Writes that create records, move money or change cover (saving a quote or policy, an STK push, a certificate, a claim, an SMS batch) require an Idempotency-Key header: a unique value such as a UUID that you generate per operation. If the connection drops, send the same request with the same key. We return the first response again with Idempotent-Replayed: true instead of doing the work twice.

The same key with a different body is refused with 422 idempotency_key_reused; a missing key is 400 idempotency_key_required. Keys are remembered for 24 hours per API client. Each endpoint's page says whether it needs one.

A retry-safe write cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/payment/stk/push' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7' \
  -H 'Content-Type: application/json' \
  -d '{"account": "DN-000123", "phone": "0712345678", "amount": 30175}'

Errors

Every error is an RFC 9457 problem document with content type application/problem+json: type, title, status, detail, a machine-readable code, the request id as instance and, for validation failures, errors by field. Branch on code, not on the wording of detail.

422 Unprocessable Content application/problem+json
{
    "type": "https://flexysure.com/problems/validation_failed",
    "title": "Validation failed",
    "status": 422,
    "detail": "The vehicle.year field is required.",
    "code": "validation_failed",
    "instance": "9b1d0c4e-2f3a-4b5c-8d6e-7f8091a2b3c4",
    "errors": {
        "vehicle.year": [
            "The vehicle.year field is required."
        ]
    }
}
StatusCodeWhen
400idempotency_key_requiredA write that needs an Idempotency-Key was sent without one.
401unauthenticatedNo bearer token, or it expired or was revoked.
401invalid_clientWrong client id or secret on the token endpoint.
403insufficient_scopeThe token does not carry the scope the endpoint needs.
403agent_deniedX-Agent-Code and X-Agent-Key do not match an agent of the organisation.
404not_foundNo such record, or it belongs to another organisation or agent.
422validation_failedThe body failed validation; errors lists the messages by field.
422idempotency_key_reusedThe same Idempotency-Key was sent with a different body.
429rate_limitedToo many requests; wait for Retry-After seconds.
500server_errorSomething failed on our side. Quote the instance (request id) to support.

Pagination

Lists that can grow are paginated with an opaque cursor: pass limit (1–100, default 25) and follow links.next until it is null. Cursors stay correct while new records arrive. The same lists also accept Insurance Cloud style page and per_page, which add total and last_page; prefer the cursor for large exports.

?limit=25 (cursor) JSON
{
    "data": [
        "\u2026"
    ],
    "meta": {
        "limit": 25,
        "has_more": true,
        "count": 25
    },
    "links": {
        "next": "https://flexysure.intrepidprojects.co.ke/api/v1/claims?limit=25&cursor=eyJpZCI6MTIwfQ"
    }
}
?page=2&per_page=50 JSON
{
    "data": [
        "\u2026"
    ],
    "meta": {
        "page": 2,
        "per_page": 50,
        "total": 312,
        "last_page": 7
    },
    "links": {
        "next": "https://flexysure.intrepidprojects.co.ke/api/v1/erp/policies?page=3&per_page=50",
        "prev": "https://flexysure.intrepidprojects.co.ke/api/v1/erp/policies?page=1&per_page=50"
    }
}

Rate limits

Limits are per minute. Over the limit you get 429 rate_limited with a Retry-After header in seconds. Each endpoint lists its own limit.

WhatLimit
Every endpoint (default)60 requests a minute per token, unless a different limit is set on the API client
Token endpoint10 requests a minute per IP address
ERP record lists5 requests a minute per client
Client area details, policies and policy5 requests a minute per client
Client area statement10 requests a minute per client

Agent headers

One API client can act for many agents. Send X-Agent-Code and X-Agent-Key (set on the agent's profile) and the call runs as that agent: quotes and policies are recorded against them, and lists only show their own clients and policies. Without the headers the call runs with the API client's own visibility. A code and key that do not match return 403 agent_denied. Endpoints that accept the headers say so.

Quote as agent KK01 cURL
curl -X POST 'https://flexysure.intrepidprojects.co.ke/api/v1/motor/quote' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Accept: application/json' \
  -H 'X-Agent-Code: KK01' \
  -H "X-Agent-Key: $AGENT_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "class": "Motor",
    "coverage": "Private",
    "scope": "Comprehensive",
    "cover_period": "annual",
    "year": 2018,
    "value": 1000000,
    "pll": 4,
    "insurer_id": [
        1,
        2
    ]
}'

Migrating from Insurance Cloud

46 endpoints keep the paths, field names and response shapes of Insurance Cloud's Open API v1.0, so an existing integration moves over by changing the base URL and the credentials. The token endpoint accepts the key and passkey body, and paginated lists accept page and per_page.

The other 51 are additions, marked Flexysure only throughout these docs: scoped tokens, idempotent writes, policy endorsement and cancellation, payment status, premium finance, claims writes, webhooks and more.

GroupSame contractAdded by Flexysure
Authentication POST /oauth/token —
Reference data GET /insurers GET /branches GET /risk-managers GET /sales-people GET /policy/taxes GET /motor/benefits GET /products GET /me
Motor POST /motor/quote POST /motor/save_quote POST /motor/save —
Medical GET /medical/limits POST /medical/quote POST /medical/save GET /medical/census-template
Travel POST /travel/quote POST /travel/save —
Standard products GET /standard/products GET /standard/quote POST /standard/save —
Policies and quotes — GET /policies GET /policies/{uuid} POST /policies/{uuid}/endorse GET /policies/{uuid}/cancellation-quote POST /policies/{uuid}/cancel POST /policies/{uuid}/renewal-quote GET /quotes/{uuid}
Payments POST /payment/stk/push GET /payment/stk/{uuid} GET /receipts GET /receipts/{number} GET /clients/{client_no}/balance
Prospects POST /prospects GET /prospects GET /prospects/{uuid} PATCH /prospects/{uuid} POST /prospects/{uuid}/activities POST /prospects/{uuid}/convert
Clients — GET /clients POST /clients GET /clients/{client_no} PATCH /clients/{client_no}
Claims — GET /claims POST /claims GET /claims/{uuid} POST /claims/{uuid}/status POST /claims/{uuid}/documents
Premium finance — GET /ipf/offers POST /ipf/applications GET /ipf/applications/{uuid} POST /ipf/applications/{uuid}/otp POST /ipf/applications/{uuid}/sign GET /ipf/loans/{uuid} GET /ipf/loans/{uuid}/agreement POST /ipf/loans/{uuid}/deposit POST /ipf/loans/{uuid}/early-settlement
ERP exports GET /erp/clients GET /erp/policies GET /erp/claims —
Client area POST /client/login POST /client/verify-otp POST /client/logout POST /client/register GET /client/details POST /client/policies POST /client/policies/all GET /client/policy/{id} POST /client/statement GET /client/files/kyc/{uuid} GET /client/files/policies/{policy}/risk-note GET /client/files/debit-notes/{note} GET /client/files/receipts/{receipt} GET /client/files/certificates/{certificate} GET /client/loans GET /client/loans/{uuid} POST /client/policy/{id}/pay GET /client/claims POST /client/claims
Motor certificates (DMVIC) POST /dmvic POST /dmvic/agent POST /dmvic/get-certificate POST /dmvic/double-insurance POST /dmvic/stock POST /dmvic/cancel GET /certificates/{number}/verify
SMS POST /sms/send GET /sms/sent GET /sms/balance GET /sms/{uuid}
Webhooks — GET /webhooks POST /webhooks GET /webhooks/events GET /webhooks/{id} DELETE /webhooks/{id} GET /webhooks/{id}/deliveries POST /webhook-deliveries/{id}/retry

Webhooks are new: subscribe to events instead of polling for payments, activations and certificates.