Insurance Cloud Open API
Build secure, reliable insurance integrations with a clear and versioned API.
About the API #
The Insurance Cloud Open API enables approved partners and external applications to securely connect with the Insurance Cloud platform. It provides standardized access to selected Insurance Cloud services, allowing partners to build reliable integrations and automate insurance workflows.
The API documentation will be released progressively. Each release will introduce additional endpoints and capabilities.
API credentials are confidential. Never expose your Insurance Cloud key or passkey in browser-side code, public repositories, screenshots, or application logs.
Always send API requests over HTTPS. Unencrypted HTTP can expose credentials, access tokens, customer information, policy data, and payment details in transit.
Base URL #
The base URL includes the /api prefix. The link is the same account link used to access your Insurance Cloud system.
https://demo.inscloud.net/apihttps://demo.inscloud.net/apiVersioning #
This documentation describes v1.0, released on 27 July 2026. Future versions and releases will be identified clearly so integrations can adopt new capabilities predictably.
Authentication #
Authenticate with your approved integration credentials to receive an access token. Send that token with subsequent protected requests using the Bearer authorization scheme.
Bearer your_access_tokenAuthenticate #
{{base_url}}/authAuthenticates an approved integration using its Insurance Cloud key and passkey. If the credentials are valid, the endpoint returns an access token that should authorize subsequent API requests.
In Insurance Cloud, go to API → API Keys. Copy your Insurance Cloud key and passkey, then store them in secure server-side environment configuration or a secrets manager.
Headers
Acceptapplication/jsonYesContent-Typeapplication/jsonYesRequest body
inscloudkeystring · requiredYour approved Insurance Cloud key.passkeystring · requiredThe passkey associated with the key.Examples
{
"inscloudkey": "your_inscloud_key",
"passkey": "your_passkey"
}
{
"token": "1|your_access_token",
"expires_in": 604800
}
Response body
tokenstringBearer access token for all protected endpoints. The same token is returned on repeat calls until it expires.expires_inintegerSeconds until the token expires. Tokens are valid for 7 days from issue.expires_atstring · upcomingExpiry date and time of the token in ISO 8601, e.g. 2026-10-21T09:30:00+03:00. Not returned yet. Please plan for it in your integration now.expires_atA future release will add expires_at to this response, giving the exact date and time the token expires. Please scope it now: accept it as an expected field, store it with the token, and call POST /api/auth again shortly before that time (or when any request returns 401). Until then, use expires_in. Clients that reject unknown response fields should be updated to allow it.
Responses
Credentials are valid and an access token is returned.
The supplied key or passkey is invalid.
A required credential field was not supplied.
SMS #
Send one or more SMS messages, review sent-message history, and check the available SMS-unit balance. All SMS endpoints are protected and require an access token from the authentication endpoint.
Bearer your_access_tokenSend SMS #
{{base_url}}/sms/sendSends one or more SMS messages in a single request. Each result is reported separately, making partial delivery failures easy to identify.
Headers
AuthorizationBearer your_access_tokenYesAcceptapplication/jsonYesContent-Typeapplication/jsonYesRequest body
smsarray · requiredAt least one message object.sms[].phonestring · requiredRecipient phone number, up to 20 characters.sms[].messagestring · requiredMessage content.sms[].policy_idinteger · optionalRelated policy ID. Must be at least 1 when supplied.sms[].transactionstring · optionalMessage-specific transaction label, up to 255 characters.transactionstring · optionalDefault label for all messages. Defaults to API SMS.Examples
{
"transaction": "Policy notification",
"sms": [
{
"phone": "254718888888",
"message": "Your policy is ready.",
"policy_id": 125
}
]
}
{
"status": "success",
"message": "1 SMS sent, 0 failed.",
"summary": {"total": 1, "sent": 1, "failed": 0},
"results": [
{
"index": 0,
"phone": "254718888888",
"message": "Your policy is ready.",
"policy_id": 125,
"transaction": "Policy notification",
"sent": true,
"error": null
}
]
}
Responses
Every SMS in the request was accepted successfully.
One or more messages failed. Inspect each item’s sent and error values.
The payload is missing a required field or contains an invalid value.
Sent messages #
{{base_url}}/sms/sentReturns sent SMS records in reverse chronological order, with date filtering and pagination.
Headers
AuthorizationBearer your_access_tokenYesAcceptapplication/jsonYesQuery parameters
fromdate · optionalStart date. Defaults to the first day of the current month.todate · optionalEnd date. Defaults to today and cannot be before from.pageinteger · optionalPage number. Defaults to 1.per_pageinteger · optionalRecords per page, from 1 to 100. Defaults to 50.Examples
{
"status": "success",
"filters": {"from": "2026-07-01", "to": "2026-07-27"},
"summary": {
"total": 1,
"per_page": 20,
"current_page": 1,
"last_page": 1
},
"sms": [
{
"id": 42,
"phone": "254718888888",
"message": "Your policy is ready.",
"policy_id": 125,
"transaction": "Policy notification",
"added_by": 7,
"created_at": "2026-07-27T08:30:00.000000Z",
"updated_at": "2026-07-27T08:30:00.000000Z"
}
]
}
Responses
Returns the applied filters, pagination summary, and records in the sms array.
A date or pagination value is invalid.
SMS balance #
{{base_url}}/sms/balanceReturns the current SMS-unit balance available to the authenticated integration.
Headers
AuthorizationBearer your_access_tokenYesAcceptapplication/jsonYesExamples
{
"status": "success",
"balance": 125
}
Responses
The balance field contains the available SMS units.
M-Pesa Payments #
Initiate an M-Pesa STK Push prompt on a customer’s phone for an account or transaction reference.
Bearer your_access_tokenIn the Insurance Cloud side menu, go to APIs → M-Pesa. Configure the Consumer Key, Consumer Secret, Short Code, and Passkey, then register the callback URL where required.
Initiate STK Push #
{{base_url}}/payment/stk/pushSends an M-Pesa payment prompt to the supplied phone number and records the Safaricom checkout request for callback processing.
Headers
AuthorizationBearer your_access_tokenYesAcceptapplication/jsonYesContent-Typeapplication/jsonYesRequest body
accountstring · requiredAccount, invoice, risknote, or transaction reference shown in the M-Pesa prompt.amountnumber · requiredAmount to request. Formatting characters are removed before submission.phonestring · requiredKenyan phone number in 07XXXXXXXX or 2547XXXXXXXX format.Examples
{
"account": "POL-2026-001",
"amount": 52736,
"phone": "0718888888"
}
{
"merchant_request_id": "29115-34620561-1",
"checkout_request_id": "ws_CO_280720261230001234"
}
Responses
Returns Safaricom merchant and checkout request IDs. Use the checkout request ID to check STK status. The final payment result is also delivered asynchronously to the configured callback.
Returned for insecure traffic, missing M-Pesa configuration, an invalid phone number, authentication failure, or an STK Push rejection.
STK Status #
{{base_url}}/payment/stk/status/{checkoutRequestId}Check the result of an STK Push using the checkout_request_id returned when the prompt was initiated. This GET request has no request body.
Headers
AuthorizationBearer your_access_tokenYesAcceptapplication/jsonYesPath parameter
checkoutRequestIdstring · requiredThe STK Push checkout request ID, for example ws_CO_280720261230001234.Response fields
statusstringpending, success, or failed. HTTP 200 alone does not confirm payment.messagestring | nullProvider result description; may be null while pending.receipt_numberstring | nullM-Pesa receipt number; may remain null until the callback supplies it.amountdecimal stringThe recorded payment amount.email_sentbooleanWhether the receipt email has been sent.sms_sentbooleanWhether the receipt SMS has been sent.receipt_urlstring | nullSigned receipt PDF URL valid for seven days, or null until a receipt transaction exists.Poll while status is pending; stop on success or failed. Pending provider checks are throttled to once every ten seconds. Receipt details and notification flags may still be incomplete when payment first succeeds.
Examples
curl --request GET \
'{{base_url}}/payment/stk/status/ws_CO_280720261230001234' \
--header 'Authorization: Bearer your_access_token' \
--header 'Accept: application/json'
{
"status": "pending",
"message": null,
"receipt_number": null,
"amount": "52736.00",
"email_sent": false,
"sms_sent": false,
"receipt_url": null
}
{
"status": "success",
"message": "The service request is processed successfully.",
"receipt_number": "UJ16ABC123",
"amount": "52736.00",
"email_sent": true,
"sms_sent": true,
"receipt_url": "https://your-domain.com/receipt/example?expires=1792800000&signature=example"
}
{
"status": "failed",
"message": "Request cancelled by user",
"receipt_number": null,
"amount": "52736.00",
"email_sent": false,
"sms_sent": false,
"receipt_url": null
}
Responses
Returns the current payment status, receipt details, and notification flags, including pending and failed payments.
A valid Sanctum bearer token is required.
No STK Push record matches the checkout request ID.
DMVIC motor certificates #
Issue and retrieve DMVIC motor certificates, validate possible double insurance, and inspect an insurer’s DMVIC certificate stock. All endpoints require a valid Insurance Cloud Bearer token.
Bearer your_access_tokenIssue certificate #
{{base_url}}/dmvicIssues DMVIC certificates for one or more vehicles linked to the policy identified by the risknote.
Request body
risknoteinteger · requiredAn existing risknote linked to a valid policy.emailemail · requiredPolicyholder contact email.phonestring · requiredPolicyholder phone number containing 9–15 digits.vehiclesarray · requiredAt least one vehicle.vehicles[].registrationstring · requiredAn existing vehicle registration attached to the risknote’s policy.vehicles[].start_datedate · requiredToday or later, within the policy period and not after expiry.vehicles[].expiringdate · requiredOn or after the start date and not beyond the policy end date.Examples
{
"risknote": 100245,
"email": "client@example.com",
"phone": "254718888888",
"vehicles": [{
"registration": "KDA 123A",
"start_date": "2026-07-27",
"expiring": "2027-07-26"
}]
}
Responses
Returns success: true after successful issuance.
The risknote, vehicle association, dates, policy, or DMVIC setup is invalid.
Agent certificate issuance #
{{base_url}}/dmvic/agentIssues the next eligible certificate stage for an agent-owned policy. Insurance Cloud calculates the certificate period from the policy, instalments, receipts, and certificates already issued.
Additional headers
X-Agent-Codeyour_agent_codeYesX-Agent-Keyyour_agent_keyYesRequest body
policy_idinteger · requiredPolicy belonging to the authenticated agent.The policy must have a risknote, vehicle, premium details, a valid remaining certificate period, and sufficient receipts for the current instalment stage.
Responses
The eligible DMVIC certificate stage was issued.
The policy does not belong to the supplied agent.
Credentials, policy setup, payment, instalment stage, or certificate period failed validation.
Get certificate #
{{base_url}}/dmvic/get-certificateRetrieves a previously issued certificate using its DMVIC certificate number.
Request body
CertificateNumberstring · requiredThe exact DMVIC certificate number.A successful request returns the certificate body using DMVIC’s response content type. Save the response as a file; do not parse it as JSON.
Responses
Returns a binary certificate response.
CertificateNumber was not supplied.
The upstream service did not return an access token.
Validate double insurance #
{{base_url}}/dmvic/double-insuranceChecks whether a vehicle has overlapping insurance for the requested cover period.
Request body
registrationstring · requiredVehicle registration number.chassisstring · optionalVehicle chassis number. Registration is used as fallback.start_datedate · requiredToday or later and not after expiring.expiringdate · requiredOn or after start_date.Responses
Returns overlapping certificate details when found, or No double insurance found.
A vehicle or date field is invalid.
Member company stock #
{{base_url}}/dmvic/stockReturns DMVIC certificate stock information for a configured insurer member company.
Request body
insurerstring · requiredThe insurer’s configured DMVIC member company ID.Responses
The DMVIC response is returned inside the data array.
The value does not match a configured insurer DMVIC ID.
Reference Data #
Load the IDs and allowed values required by quotation and policy-creation requests. These endpoints supply insurers, branches, risk managers, salespeople, policy taxes, Motor benefits, and vehicle makes and models for use with /motor/save, /standard/save, /medical/save, and /travel/save.
Bearer your_access_tokenInsurers #
{{base_url}}/insurersReturns insurer IDs, short and legal names, and a logo URL when available. Use ?search=term to filter by name.
Use data[].id as policy.insurer_id.
Branches #
{{base_url}}/branchesReturns branch IDs, codes, locations, and cities. Use data[].id as client.branch_id.
Risk managers #
{{base_url}}/risk-managersReturns active risk-manager user IDs, names, and email addresses. Use data[].id as client.risk_manager_id.
Sales people #
{{base_url}}/sales-peopleReturns salesperson IDs, names, codes, and branch IDs. Use data[].id as client.sales_person_id when applicable.
Policy taxes #
{{base_url}}/policy/taxesReturns configured policy-tax IDs and names. Use data[].id as taxes[].tax_id.
Motor benefits #
{{base_url}}/motor/benefitsReturns Motor benefit IDs and names. Use data[].id as vehicles[].benefits[].benefit_id.
Maximum ten requests per minute per IP.
Vehicle makes #
{{base_url}}/vehicle/makesReturns vehicle makes from the vehicle catalogue: global makes from the US NHTSA vehicle database (refreshed monthly), the local market list (for example Bajaj, TVS, Sinotruk), and makes added from saved policies. Use data[].name as vehicles[].make, and data[].id with Vehicle models.
Query parameters
searchstring · optionalPart of the make name, e.g. toy.typestring · optionalOne of car, truck, mpv, bus. Makes without a recorded type (local and learned makes) are always included.Response fields
idintegerMake ID, for /vehicle/models?make_id=.namestringMake name.sourcestringnhtsa (NHTSA vPIC), local (market list) or learned (added from a saved policy).vehicle_typesstring[]NHTSA vehicle types the make builds; empty for local and learned makes.Responses
count gives the number of makes.
type is not one of the listed values.
Vehicle models #
{{base_url}}/vehicle/modelsReturns the models of one make. Models from the NHTSA database are fetched the first time a make is requested and refreshed every 30 days, so the first call for a make can take a few seconds. Local market models (for example Toyota Probox, Premio, Fielder) and models added from saved policies are always included. Use data[].name as vehicles[].model, and data[].body (the model's usual body type, when known) as a default for vehicles[].body.
Query parameters
makestring · conditionalMake name (not case-sensitive), instead of make_id.searchstring · optionalPart of the model name, e.g. cor.Responses
Includes the make (make.id, make.name) and count.
No make with that ID or name.
Neither make_id nor make was given.
Makes and models not in the catalogue can still be sent on /motor/save; they are added to the catalogue when the policy is saved.
Quotations and underwriting #
Generate insurer options and convert a selected option into a Motor, Medical, Standard, or Travel policy. Quote endpoints calculate options; /save_quote stores a quotation; product /save endpoints create policies.
Before creating a policy, call Verify client to find out whether the client already exists and whether a new client's details would be accepted.
Verify client #
{{base_url}}/clients/verifyChecks whether a client already exists, using the same rules as the policy /save endpoints (Motor, Medical, Standard, Travel, Marine): a client is matched on ID number (idno). With X-Agent-Code and X-Agent-Key headers, only that agent's clients count. For a new client it also tells you whether the email or phone already belongs to another client, which the save would reject.
idnostring · requiredThe client's national ID or passport number.emailstring · optionalChecked for new clients only.phonestring · optionalChecked for new clients only, as entered (e.g. 254718888888).What to do next
exists: trueClient found; details and active policies are returned in client.Save the policy with the same idno; the existing client is used.exists: false, can_create: trueNew client.Send the full client object with the policy.exists: false, can_create: falseNew client, but the fields in conflicts belong to another client.Confirm the details with the client before saving.Responses
See exists, and for new clients can_create and conflicts. Other clients' details are never returned.
Maximum 60 checks per minute per account.
Generate motor quote #
{{base_url}}/motor/quoteReturns matching insurer rates, benefits, taxes, markup, instalments, and limits of liability.
classstring · requiredMotor, Tuktuk, or Motorcycle.coveragestring · requiredUsage class such as Private, a specific Commercial class, or a specific PSV class.scopestring · requiredComprehensive or TPO.cover_periodstring · requiredannual or tor; defaults to annual.daysinteger · optionalTOR only: number of days on risk (e.g. 30 or 60). When empty, every period set up for each insurer is returned as its own option, each with its days.year, value, tonnage, pllnumber · conditionalRequired when the selected rate or benefit calculation uses the value.insurer_idinteger[] · optionalRestrict results to one or more insurers.Responses
Matching plans are returned in options.
Review the validation errors or returned quote criteria.
Save motor quotation #
{{base_url}}/motor/save_quoteStores the customer, vehicle, and one or more calculated insurer options as a quotation. This does not create a policy.
clientname, email, phone, idnoOptional agentcode links the quotation to an agent.vehiclevalue, year, reg_noAlso accepts coverage, scope, subcover, tonnage, make, and model.quotes[]insurer_id, rate, basic, taxes, totalCalculated options; benefits may contain benefit_name and amount.Returns the saved quotation details and options.
Create motor policy #
{{base_url}}/motor/saveCreates the client and motor policy from the selected quote option, including vehicles, taxes, and selected benefits.
clientname, email, phone, idno, risk_manager_id, branch_idOptional PIN and sales person. An existing client (same idno) is reused; check first with Verify client.policydates, insurer_id, class, coverage, scope, total_basic, taxes, premium, premium_instalmentsInstalments must be 1–4.policy.limits_of_liabilityoptional — the selected option's limits_of_liability from motor/quote, as returnedPrinted on the risk note as one "Item: Limit" line each.vehicles[]coverage, regno, value, basic_premium, rateMake and model are required for Comprehensive cover.taxes[]tax_id, rate, amountEach tax must exist in policy-tax setup.Returns policy ID, risknote, client number, and client key. Keep the id to edit the policy before it is authorised.
Maximum three attempts per 15 seconds per IP.
Edit motor policy #
{{base_url}}/motor/policies/{id}Edits a policy created with Create motor policy, using the id it returned. Send the policy as it should now be: the policy details, taxes and vehicles (with their benefits) replace what was saved. The client and risk note number do not change. PATCH is also accepted.
policydates, insurer_id, class, coverage, scope, total_basic, taxes, premium, premium_instalmentsSame fields and rules as Create motor policy. Optional limits_of_liability and markup_value.vehicles[]coverage, regno, value, basic_premium, rateThe full list of vehicles; any vehicle left out is removed. Make and model are required for Comprehensive cover.taxes[]tax_id, rate, amountThe full list of taxes.When a policy can be edited
Only while it is unauthorised. Editing is refused once the policy is authorised or cancelled, a receipt has been allocated to it, or a certificate has been issued. Agents (with X-Agent-Code and X-Agent-Key) can only edit policies written under their own agency.
Responses
Returns the policy id, its unchanged risknote and the new premium.
No motor policy with this id, or it belongs to another agent.
The message says why: authorised, cancelled, receipted or certificate issued.
Same rules as Create motor policy.
Maximum three attempts per 15 seconds per IP.
Medical limits #
{{base_url}}/medical/limitsReturns the unique configured inpatient limits in ascending order. Limited to ten requests per minute per IP.
Returns an array of id and limit objects.
Generate medical quote #
{{base_url}}/medical/quoteCalculates available medical plans using principal age, spouse age, number of children, and inpatient limit.
principal_agenumber · requiredPrincipal member’s age.spouse_agenumber · requiredUse 0 when no spouse is included.childrennumber · requiredNumber of children.limit_from, limit_tonumber · requiredRequested inpatient limit range.Responses
Returns matching insurer plans and benefit options in options.
One or more required ages, child count, or limit values are invalid.
Create medical policy #
{{base_url}}/medical/saveCreates a medical policy for a client and family members using the selected insurer plan.
clientname, email, phone, idno, risk_manager_id, branch_idCustomer details.members[]name, type, dob, product_namePrincipal, spouse, and child records.policydates, insurer_id, inpatient_limit, basic, taxes, premiumSelected plan and premium totals.policy.outpatient_limit, maternity_limit, dental_limit, optical_limitoptional — the limits chosen from the medical/quote optionShown on the risk note against the principal, with inpatient_limit.taxes[]tax_id, rate, amountApplied policy taxes.Returns policy ID, risknote, client number, and key.
Standard products #
{{base_url}}/standard/productsLists supported standard product IDs and names.
Returns products currently configured for IDs 20, 27, 29, 35, and 49.
Generate standard quote #
{{base_url}}/standard/quoteReturns insurer options, premiums, benefits, logo URLs, and brochures for a standard product.
product_idinteger · requiredProduct returned by /standard/products.insurer_idinteger[] · optionalLimit options to selected insurers.ageinteger · optionalNon-negative age used to select an age-band premium.Create standard policy #
{{base_url}}/standard/saveCreates a policy for a supported standard product with its taxes and optional benefit schedule.
clientname, email, phone, idno, risk_manager_id, branch_idCustomer details.policyproduct_id, dates, insurer_id, coverName, basicPremium, sumInsured, taxes, premiumProduct ID must be supported.taxes[], benefits[]arraysTaxes and optional schedule items.Generate travel quote #
{{base_url}}/travel/quoteReturns matching insurer plans based on destination, dates, rate type, and traveller count.
rate_typestring · requiredConfigured normal, student, or inbound rate type.traveling_from, traveling_tostring · requiredOrigin and destination country.number_of_travelersinteger · requiredAt least 1.departure_date, return_datedate · requiredReturn cannot be before departure.Create travel policy #
{{base_url}}/travel/saveCreates a travel policy for the selected quote and stores each traveller and beneficiary record.
clientname, email, phone, idno, risk_manager_id, branch_idCustomer details.policydates, insurer_id, currency_id, basicPremium, taxes, premium, sumInsured, coverNameOptional quoteId links the source quote.travel_infodeparture, return, travelling_from, travelling_to, trip_typeJourney information.travellers[]nameDOB and identity, contact, passport, and beneficiary fields are supported.Policy currency fields
policy.currency_idinteger · requiredMust reference an existing ID in currencies.policy.conversion_ratenumeric · optionalCurrency conversion rate applied to premiums, taxes, and commission. Use 1 when no conversion is needed.Returns policy ID, risknote, client number, and client key.
Response fields
messagestringSuccess message: Policy created successfully.idintegerID of the newly created policy, matching the /motor/save response.risknoteintegerRisknote number assigned to the policy.client_nostringClient number associated with the policy.client_keystringClient access key.Prospects #
Create a prospect (lead) in the CRM, with an optional product breakdown and assignee list. This mirrors the "Add Prospect" form in Insurance Cloud.
Bearer your_access_tokenCreate prospect #
{{base_url}}/prospectsCreates a single prospect. Only p_name and status are required — everything else is optional.
Headers
AuthorizationBearer your_access_tokenYesAcceptapplication/jsonYesContent-Typeapplication/jsonYesRequest body
p_namestring · requiredProspect name.statusstring · requiredProspect status label.emailstring · optionalProspect email address.phonestring · optionalProspect phone number, up to 50 characters.sectorstring · optionalBusiness sector / nature of occupation.insurer_idinteger · optionalPreferred insurer ID.alt_namestring · optionalAlternative contact name.alt_phonestring · optionalAlternative contact phone.alt_emailstring · optionalAlternative contact email.start_datedate · optionalExpected cover start date.due_datedate · optionalExpected close date.follow_up_datedate · optionalNext follow-up date.notesstring · optionalFree-text notes.ratingstring · optionalProspect rating/priority label.business_source_idinteger · optionalBusiness source ID.prospect_type_idinteger · optionalClient category / type ID.productsarray · optionalProduct breakdown rows.products[].productstring · required with productsProduct name.products[].product_idinteger · optionalProduct ID, when known.products[].comm_ratenumeric · optionalCommission rate.products[].premiumnumeric · optionalExpected premium for this product.products[].commissionnumeric · optionalExpected commission for this product.assign_toarray of integers · optionalUser IDs to assign the prospect to.Examples
{
"p_name": "Jane Doe",
"status": "New",
"email": "jane@example.com",
"phone": "254718888888",
"sector": "Retail",
"products": [
{
"product": "Motor Comprehensive",
"comm_rate": 10,
"premium": 50000,
"commission": 5000
}
],
"assign_to": [7]
}
{
"status": "success",
"message": "Prospect created successfully.",
"prospect": {
"id": 154,
"p_name": "Jane Doe",
"status": "New",
"expected_prem": 50000,
"expected_comm": 5000,
"created_at": "2026-08-28T09:12:00+00:00"
}
}
Responses
Returns the new prospect's ID and key fields.
A required field is missing or a value is invalid.
The prospect could not be created. Nothing was saved.
ERP Records #
Retrieve paginated client, policy, and claim records available to the authenticated ERP account.
Bearer your_access_tokenERP employees can access all records. Salespeople see their assigned records. Agents see records associated through client-agent or agent-production relationships. Access is always determined by the authenticated account.
List clients #
{{base_url}}/erp/clientsReturns clients visible to the authenticated ERP employee, salesperson, or agent, ordered by client name.
Query parameters
pageinteger · optionalPage number. Defaults to 1.per_pageinteger · optionalRecords per page, from 1 to 100. Defaults to 15.Response data
Each client includes contact and identity details, address information, the assigned salesperson, and associated agents. Pagination is returned in meta and links.
Maximum five requests per minute.
List policies #
{{base_url}}/erp/policiesReturns policies visible to the authenticated account, ordered by most recent start date.
Query parameters
statusinteger · required0 or 1 filters by status; 2 returns all statuses.startingdate · optionalPolicy start-date range beginning.endingdate · optionalRange end, on or after starting. Date filtering applies when both dates are supplied.pageinteger · optionalPage number. Defaults to 1.per_pageinteger · optionalRecords per page, from 1 to 100. Defaults to 15.Response data
Policy records include insurer, client, product, cover dates, risknote, premium, receipts, balance, salesperson, and agents.
Maximum five requests per minute.
List claims #
{{base_url}}/erp/claimsReturns claims for policies visible to the authenticated account, ordered by most recent incident date.
Query parameters
startingdate · optionalReported-date range beginning.endingdate · optionalReported-date range end. Supply both dates to filter.typestring · optionalLegal or Non Legal.pageinteger · optionalPage number. Defaults to 1.per_pageinteger · optionalRecords per page, from 1 to 100. Defaults to 20.Response data
Claim records include policy and insurer references, incident and reporting dates, status and progress, client, claimant, amounts, salesperson, and agents.
Maximum five requests per minute.
Client Area #
Log in with an email or phone, verify the OTP, then retrieve client details, policies and statements. Register a new client when no existing client record is available.
All client endpoints require HTTPS. Login, OTP verification and logout do not require an integration Bearer token. Registration and client data endpoints require an integration Bearer token from POST /auth. Send Accept: application/json and Content-Type: application/json for JSON requests.
After OTP verification, use user.client_no as X-Client-No and user.client_key as X-Client-Key. Registration returns these as client.client_no and user.client_key. These additional headers are required for details, policies and statements.
Bearer your_access_tokenJD001IC_your_client_keyCommon errors: 401 for missing/invalid Bearer authentication; 422 for invalid inputs or client credentials. Insecure requests return 403 for login, verification, logout and registration, and 400 for the client data endpoints.
Request login OTP #
{{base_url}}/client/loginProvide an email or phone exactly as saved on the account. If both are supplied, both must match. A missing ClientUser is created from a matching clients record; contacts absent from both return an error. The same code is sent to each available saved email and phone using email and SMS. No client key is returned yet. To resend, repeat this request with the same email or phone and use the new otp_id returned on success.
Headers
Accept: application/json, Content-Type: application/json.
Request body
emailstring · conditionalValid email, maximum 255 characters. Required when phone is absent.phonestring · conditionalPhone, maximum 50 characters. Required when email is absent.Responses
No password is required. For phone login, use {"phone":"0712345678"}. Codes expire after five minutes. Up to three requests per five minutes are allowed per identifier and per user. Errors: 403 unknown or locked/disabled account; 422 invalid input or no delivery contact; 429 request limit; 503 delivery failure.
Examples
curl --request POST \
'{{base_url}}/client/login' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"email": "jane@example.com"
}'
{
"status": "success",
"message": "OTP sent successfully",
"otp_id": "550e8400-e29b-41d4-a716-446655440000",
"expires_in": 300,
"channels": [
"email",
"sms"
]
}
Verify login OTP #
{{base_url}}/client/verify-otpVerify the code using the otp_id returned by login. Successful verification consumes the code and returns the existing login response. Save user.client_no and user.client_key for subsequent client requests.
Headers
Accept: application/json, Content-Type: application/json.
Request body
otp_idUUID · requiredChallenge identifier returned by /client/login.otpstring · requiredSix-digit verification code.Responses
Five failed verification attempts exhaust a challenge. Request a new OTP after expiry or exhaustion. Errors: 422 invalid, expired or already used code; 429 attempt limit; 403 locked/disabled account. A successful login replaces the previous client key.
Examples
curl --request POST \
'{{base_url}}/client/verify-otp' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"otp_id": "550e8400-e29b-41d4-a716-446655440000",
"otp": "123456"
}'
{
"status": "success",
"message": "Login successful",
"user": {
"name": "Jane Doe",
"email": "jane@example.com",
"phone": "0712345678",
"department_id": null,
"department": null,
"company": "Jane Doe",
"client_no": "JD001",
"national_id": "12345678",
"kra_pin": "A000000001Z",
"client_key": "IC_your_client_key",
"is_admin": false,
"risk_manager_id": 1
}
}
Logout #
{{base_url}}/client/logoutClears the matching client user's login key. Use user.client_no and user.client_key returned by OTP verification. After success, discard the saved client key. No integration Bearer token is required.
Headers
Accept: application/json, Content-Type: application/json. HTTPS is required.
Request body
client_nostring · requiredClient number returned at login.client_keystring · requiredCurrent client key returned at login. Send in the JSON body.Responses
The client key is revoked.
Missing fields return Invalid input with validation errors. Invalid or already revoked keys return Invalid credentials.
Use HTTPS.
Examples
curl --request POST \
'{{base_url}}/client/logout' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"client_no": "JD001",
"client_key": "IC_your_client_key"
}'
{
"status": "success",
"message": "Logout successful"
}
Register client #
{{base_url}}/client/registerCreates an individual or corporate client and its client user. Registration currently requires a contact password and returns a client key immediately. Use client.client_no and user.client_key for client headers.
Headers
Authorization: Bearer your_access_token, Accept: application/json, Content-Type: application/json.
Request body
typestring · requiredindividual or corporate.companyobject · conditionalRequired for corporate registration.company.namestring · conditionalRequired for corporate; maximum 255 characters.company.phonestring · conditionalRequired for corporate; maximum 50 characters.company.emailemail · conditionalRequired for corporate; maximum 255 characters.company.kra_pinstring · conditionalRequired for corporate; maximum 50 characters.contactobject · requiredPrimary contact details.contact.namestring · requiredMaximum 255 characters.contact.phonestring · requiredMaximum 50 characters.contact.emailemail · requiredMaximum 255 characters.contact.id_nostring · conditionalRequired for individual; maximum 50 characters.contact.kra_pinstring · optionalMaximum 50 characters; nullable.contact.passwordstring · requiredAt least 8 characters.Responses
The response example abbreviates the client model, which includes additional saved client fields. Errors: 403 existing account; 422 invalid input; 429 rate limit.
Examples
curl --request POST \
'{{base_url}}/client/register' \
--header 'Authorization: Bearer your_access_token' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"type": "individual",
"contact": {
"name": "Jane Doe",
"phone": "0712345678",
"email": "jane@example.com",
"id_no": "12345678",
"kra_pin": "A000000001Z",
"password": "your_secure_password"
}
}'
{
"status": "success",
"client": {
"id": 42,
"client_no": "JD001",
"client_name": "Jane Doe"
},
"user": {
"name": "Jane Doe",
"email": "jane@example.com",
"phone": "0712345678",
"national_id": "12345678",
"kra_pin": "A000000001Z",
"client_key": "IC_your_client_key"
}
}
Client details #
{{base_url}}/client/detailsReturns the authenticated client’s identity and contact details with client documents.
Headers
Authorization: Bearer your_access_token, Accept: application/json, X-Client-No: JD001, X-Client-Key: IC_your_client_key.
No request body is required.
Responses
Each client document contains id, name, url and download_url.
Examples
curl --request GET \
'{{base_url}}/client/details' \
--header 'Authorization: Bearer your_access_token' \
--header 'Accept: application/json' \
--header 'X-Client-No: JD001' \
--header 'X-Client-Key: IC_your_client_key'
{
"status": "success",
"client": {
"id": 42,
"client_no": "JD001",
"client_name": "Jane Doe",
"email": "jane@example.com",
"mobile": "0712345678",
"pin": "A000000001Z",
"national_id": "12345678"
},
"client_documents": []
}
Client policies #
{{base_url}}/client/policiesReturns client policies ordered by most recent start date, with pagination.
Headers
Authorization: Bearer your_access_token, Accept: application/json, Content-Type: application/json, X-Client-No: JD001, X-Client-Key: IC_your_client_key.
Request body
statusinteger · required0 or 1 filters by stored policy status; 2 returns all statuses.insurer_idinteger · optionalPositive insurer ID present in policies.product_idinteger · optionalPositive product ID present in policies. Takes precedence over exclude_product_ids.exclude_product_idsinteger[] · optionalPositive product IDs to exclude when product_id is absent.startingdate · optionalStart of policy start-date range. Supply both dates to apply the filter.endingdate · optionalEnd of range, on or after starting.pageinteger · optionalMinimum 1; default 1.per_pageinteger · optional1–100; default 15.Responses
Maximum five requests per minute per client number/key. Send pagination values in a POST request with the same headers and filters; pagination links are not GET endpoints.
Examples
curl --request POST \
'{{base_url}}/client/policies' \
--header 'Authorization: Bearer your_access_token' \
--header 'Accept: application/json' \
--header 'X-Client-No: JD001' \
--header 'X-Client-Key: IC_your_client_key' \
--header 'Content-Type: application/json' \
--data '{
"status": 2,
"page": 1,
"per_page": 15
}'
{
"status": "success",
"policies": [
{
"id": 125,
"status": 1,
"transaction": "New Business",
"policy_no": "POL-001",
"product_id": 1,
"insurer": "Example Insurer",
"client": "Jane Doe",
"product": "MOTOR",
"sub_cover": null,
"currency": "KES",
"start_date": "2026-09-01",
"end_date": "2027-08-31",
"sales_type": null,
"risk_note": "RN001",
"sum_insured": 1000000,
"premium": 50000,
"receipted": 20000,
"balance": 30000
}
],
"meta": {
"current_page": 1,
"last_page": 1,
"per_page": 15,
"total": 1
},
"links": {
"first": "{{base_url}}/client/policies?page=1",
"prev": null,
"next": null,
"last": "{{base_url}}/client/policies?page=1"
}
}
All client policies #
{{base_url}}/client/policies/allReturns all matching client policies without pagination, ordered by most recent start date.
Headers
Authorization: Bearer your_access_token, Accept: application/json, Content-Type: application/json, X-Client-No: JD001, X-Client-Key: IC_your_client_key.
Request body
statusinteger · required0 or 1 filters by stored policy status; 2 returns all statuses.insurer_idinteger · optionalPositive insurer ID present in policies.product_idinteger · optionalPositive product ID present in policies. Takes precedence over exclude_product_ids.exclude_product_idsinteger[] · optionalPositive product IDs to exclude when product_id is absent.startingdate · optionalStart of policy start-date range. Supply both dates to apply the filter.endingdate · optionalEnd of range, on or after starting.Responses
Uses the same policy record fields as /client/policies. Maximum five requests per minute per client number/key.
Examples
curl --request POST \
'{{base_url}}/client/policies/all' \
--header 'Authorization: Bearer your_access_token' \
--header 'Accept: application/json' \
--header 'X-Client-No: JD001' \
--header 'X-Client-Key: IC_your_client_key' \
--header 'Content-Type: application/json' \
--data '{
"status": 2
}'
{
"status": "success",
"policies": [
{
"id": 125,
"status": 1,
"transaction": "New Business",
"policy_no": "POL-001",
"product_id": 1,
"insurer": "Example Insurer",
"client": "Jane Doe",
"product": "MOTOR",
"sub_cover": null,
"currency": "KES",
"start_date": "2026-09-01",
"end_date": "2027-08-31",
"sales_type": null,
"risk_note": "RN001",
"sum_insured": 1000000,
"premium": 50000,
"receipted": 20000,
"balance": 30000
}
]
}
Policy details #
{{base_url}}/client/policy/{id}Returns a single policy belonging to the authenticated client, including financial totals, receipts, vehicles, claims and documents.
Headers
Authorization: Bearer your_access_token, Accept: application/json, X-Client-No: JD001, X-Client-Key: IC_your_client_key.
Path parameters
idinteger · required · pathNumeric policy ID that exists in policies.Responses
receipt_allocations contains amount, reference, auth_date and receipt_url. vehicles contains registration numbers. claims includes identifiers, status, type, item, amounts, dates and narration. policy_documents contains id, name, source and a signed url valid for 30 minutes. client_documents contains id, name, url and download_url. Example document links are illustrative. A nonexistent ID returns 422; a policy outside this client returns 404. Maximum five requests per minute per client number/key/policy ID.
Examples
curl --request GET \
'{{base_url}}/client/policy/125' \
--header 'Authorization: Bearer your_access_token' \
--header 'Accept: application/json' \
--header 'X-Client-No: JD001' \
--header 'X-Client-Key: IC_your_client_key'
{
"status": "success",
"policy": {
"id": 125,
"status": 1,
"transaction": "New Business",
"policy_no": "POL-001",
"insurer": "Example Insurer",
"client": "Jane Doe",
"product": "MOTOR",
"sub_cover": null,
"currency": "KES",
"start_date": "2026-09-01",
"end_date": "2027-08-31",
"sales_type": null,
"risk_note": "RN001",
"sum_insured": 1000000,
"premium": 50000,
"receipted": 20000,
"balance": 30000,
"marine_dmvic": 125,
"risk_note_link": "https://example.inscloud.net/policy-document-link",
"invoice_link": "https://example.inscloud.net/invoice-link",
"receipt_allocations": [],
"vehicles": [],
"claims": [],
"policy_documents": [],
"client_documents": []
}
}
Client statement #
{{base_url}}/client/statementReturns statement transactions within the requested authorization-date range, beginning with an opening-balance row.
Headers
Authorization: Bearer your_access_token, Accept: application/json, Content-Type: application/json, X-Client-No: JD001, X-Client-Key: IC_your_client_key.
Request body
startingdate · requiredStart date, for example 2026-09-01.endingdate · requiredEnd date, on or after starting.Responses
Statement rows contain date, reference, insurer_ref, transaction, insurer, policy_no, narration, dr, cr and running balance. Zero debit or credit values are returned as empty strings. Maximum ten requests per minute per client number/key.
Examples
curl --request POST \
'{{base_url}}/client/statement' \
--header 'Authorization: Bearer your_access_token' \
--header 'Accept: application/json' \
--header 'X-Client-No: JD001' \
--header 'X-Client-Key: IC_your_client_key' \
--header 'Content-Type: application/json' \
--data '{
"starting": "2026-09-01",
"ending": "2026-09-30"
}'
{
"status": "success",
"client": "Jane Doe",
"client_no": "JD001",
"starting": "2026-09-01",
"ending": "2026-09-30",
"opening_balance": 0,
"closing_balance": 0,
"total_debit": 0,
"total_credit": 0,
"statement": [
{
"date": "2026-09-01",
"reference": "",
"insurer_ref": "",
"transaction": "",
"insurer": "",
"policy_no": "",
"narration": "Opening Balance",
"dr": "",
"cr": "",
"balance": 0
}
]
}
More capabilities are coming
Additional endpoint groups and workflows will appear here as they are released.