Person-based coverage with age/gender rating
Asset-based coverage with factor rating
This choice determines which product classes and rating methods are available.
Update benefit rates for existing launched products. Download the product's CSV template, fill in the rates, then upload to replace the current rate entries.
Filter and review all API mutations for the selected organisation. Uses GET /api/v1/audit-logs.
| Timestamp | User | Action | Resource | IP Address | Request ID | Copy |
|---|---|---|---|---|---|---|
| Select filters and click Search to load audit entries. | ||||||
Month-end scans active/suspended policies, marks overdue premiums, applies anniversary premium and benefit indexation, and evaluates lapse candidates.
| Product | Premiums | Claims | Loss Ratio |
|---|---|---|---|
| No data yet. | |||
| Role | Display Name | Email Address | Active | Actions |
|---|---|---|---|---|
| Loading senders... | ||||
| Email Type | Role | Sender Email |
|---|---|---|
| Loading mappings... | ||
Base URL: http://localhost:8080
Multi-tenant support. All data is scoped by org_id query parameter.
/api/organizations
List all organizations
/api/organizations
Create a new organization
{
"name": "string",
"slug": "string",
"description": "string"
}
Read-only reference tables seeded from SA Insurance Act Schedule 2.
/api/product-classes
List all 23 product classes (6 LIFE + 17 NON_LIFE)
/api/benefit-types
List all 21 benefit types (DEATH, DISABILITY, FUNERAL, etc.)
/api/benefit-types/by-class/{class_code}
Get allowed benefit types for a specific product class
Benefit-level rate tables with optional non-life factors (zone, occupation class, vehicle group, smoker).
/api/rate-tables
Create a rate table with entries
/api/products/{product_id}/rate-template
Download CSV template for product benefits
/api/products/{product_id}/rate-template/upload
Upload CSV rates and bind to product benefits
{
"table_name": "Credit Life Main Rates",
"table_code": "credit-life-main-rates",
"rate_basis": "PER_MILLE", // PER_MILLE | PER_CENT | FLAT
"rating_factors": ["age", "gender"],
"entries": [
{ "age_from": 18, "age_to": 25, "gender": "MALE", "rate": 0.45 },
{ "age_from": null, "age_to": null, "gender": "UNISEX", "rating_zone": "URBAN", "vehicle_group": "A", "rate": 0.32 },
{ "age_from": 26, "age_to": 30, "gender": "MALE", "smoker_status": "SMOKER", "rate": 0.58 }
]
}
Per-org business groupings under product classes.
/api/product-categories
List categories for org
/api/product-categories
Create a product category
{
"product_class_id": "uuid",
"category_code": "INDIVIDUAL_TERM",
"category_name": "Individual Term Life",
"description": "string",
"target_market": "RETAIL | CORPORATE"
}
/api/products
List all products
/api/products
Create a new product
/api/products/{id}
Update product (AUTO clone, CLONE, or IN_PLACE)
/api/products/{id}/conformance
Run white-paper conformance checks for one product
/api/product-conformance/audit
Audit all products for conformance gaps (optionally only non-compliant)
/api/product-conformance/remediate
Normalize existing product records to baseline conformance defaults (dry-run supported)
{
"name": "string",
"slug": "string",
"description": "string",
"product_type": "TERM_LIFE | WHOLE_LIFE | FUNERAL | DISABILITY | CREDIT_LIFE",
"pricing_method": "FLAT | RATE_TABLE",
"base_premium": 199.00, // for FLAT pricing
"rate_table": [ // for RATE_TABLE pricing
{"age_from": 18, "age_to": 25, "gender": "MALE", "rate_per_thousand": 0.45},
{"age_from": 18, "age_to": 25, "gender": "FEMALE", "rate_per_thousand": 0.32}
],
"min_entry_age": 18,
"max_entry_age": 65,
"min_sum_assured": 10000,
"max_sum_assured": 5000000,
"coverage_amount": 100000, // default for flat rate
"waiting_period_days": 90,
"term_type": "FIXED_TERM | WHOLE_OF_LIFE",
"default_term_years": 20,
"premium_projection_type": "LEVEL | INDEXED | STEPPED",
"is_active": true
}
/api/products/{id}/launch
Activate a product (set is_active = true)
/api/products/{id}
Delete a product
Per-product benefit definitions with individual pricing (rate table or flat).
/api/products/{product_id}/benefits
List all benefits for a product
/api/products/{product_id}/benefits
Add a benefit to a product
{
"benefit_type_id": "uuid",
"benefit_code": "DEATH_MAIN",
"benefit_name": "Main Member Death Benefit",
"benefit_amount_type": "SUM_INSURED | FIXED | PERCENTAGE | MULTIPLE",
"default_amount": 500000,
"max_amount": 5000000,
"waiting_period_days": 180,
"is_mandatory": true,
"display_order": 1,
"member_role": "MAIN_MEMBER | SPOUSE | CHILD | PARENT | ALL",
"rate_table_id": "uuid | null", // link to rate table for age/gender pricing
"rate_basis": "PER_MILLE | PER_CENT | FLAT_AMOUNT",
"flat_premium": 59.00 // for FLAT pricing (when no rate_table_id)
}
/api/product-benefits/{benefit_id}
Delete a benefit from a product
Define what data is required to issue a policy (dynamic form fields at quote/inception).
/api/products/{product_id}/inception-rules
List inception rules for a product
/api/products/{product_id}/inception-rules
Add inception rule to a product
/api/customers
List all customers
/api/customers
Create a new customer
{
"first_name": "string",
"last_name": "string",
"email": "string",
"phone": "string",
"id_number": "string", // SA ID number (13 digits)
"date_of_birth": "YYYY-MM-DD"
}
/api/quotes/calculate
Calculate premium (stateless, no DB write)
{
"product_id": "uuid",
"customer_id": "uuid", // optional - auto-derives age/gender from DOB
"age": 30, // required for LIFE products, optional for NON_LIFE
"gender": "MALE | FEMALE | UNISEX",
"sum_assured": 500000, // headline SA (used for SUM_INSURED benefits)
"term_years": 20, // optional, default 20
"rating_inputs": { // optional non-life factors
"rating_zone": "URBAN",
"occupation_class": "PROFESSIONAL",
"vehicle_group": "A",
"smoker_status": "NON_SMOKER"
},
"benefit_overrides": [ // optional per-benefit cover amounts
{ "benefit_code": "DEATH_MAIN", "sum_assured": 500000 },
{ "benefit_code": "FUNERAL_EXP", "sum_assured": 15000 }
],
"excluded_benefits": ["CRITICAL_ILLNESS"], // optional benefits to exclude
"insured_lives": [ // per-role life assured details
{ "relationship": "MAIN_MEMBER", "age": 35, "gender": "MALE",
"date_of_birth": "1991-03-15", "first_name": "John", "last_name": "Doe" },
{ "relationship": "SPOUSE", "age": 32, "gender": "FEMALE",
"date_of_birth": "1994-06-20", "first_name": "Jane", "last_name": "Doe" }
]
}
{
"product_id": "uuid",
"product_name": "Funeral Family Plan",
"monthly_premium": 310.00,
"annual_premium": 3720.00,
"sum_assured": 500000.00,
"age": 35,
"gender": "MALE",
"term_years": 20,
"pricing_method": "BENEFIT_LEVEL",
"benefit_premiums": [
{
"benefit_code": "DEATH_MAIN",
"benefit_name": "Main Member Death",
"member_role": "MAIN_MEMBER",
"sum_assured": 500000.00,
"rate": 0.52,
"rate_basis": "PER_MILLE",
"monthly_premium": 260.00,
"pricing_method": "RATE_TABLE",
"waiting_period_days": 180
},
{
"benefit_code": "FUNERAL_EXP",
"benefit_name": "Funeral Expenses",
"member_role": "MAIN_MEMBER",
"sum_assured": 15000.00,
"rate": null,
"rate_basis": "PER_MILLE",
"monthly_premium": 50.00,
"pricing_method": "FLAT",
"waiting_period_days": 0
}
]
}
/api/quotes
Save a quote to database
{
"product_id": "uuid",
"customer_id": "uuid",
"age": 30,
"gender": "MALE",
"sum_assured": 500000,
"monthly_premium": 310.00, // from calculate response
"term_years": 20,
"benefit_premiums": [ ... ], // from calculate response
"insured_lives": [ ... ] // from calculate request
}
/api/quotes
List all quotes
/api/quotes/{id}/accept
Accept quote and create policy
{
"quote": {
"id": "uuid",
"quote_number": "QT-2026-000001",
"status": "accepted",
...
},
"policy": {
"id": "uuid",
"policy_number": "PL-2026-000001",
"effective_date": "2026-02-05",
"expiry_date": "2046-02-05",
"premium": 260.00,
"coverage_amount": 500000.00,
"status": "active"
}
}
/api/policies
List all policies (with customer name and quote number)
All policy changes are logged in an immutable event log with version snapshots for full audit trail.
/api/policies/{policy_id}/events
Query policy events with filtering
?org_id=uuid &category=LIFECYCLE|ENDORSEMENT|CLAIM|FINANCIAL // optional filter &event_type=POLICY_ISSUED|CLAIM_PAID|etc // optional filter &limit=50 // default 50 &offset=0 // for pagination
/api/policies/{policy_id}/versions
Get policy version history (snapshots)
[{
"version_number": 2,
"snapshot_date": "2026-02-11T10:30:00Z",
"change_reason": "Endorsement: CHANGE_COVER",
"change_description": "Increased main member death benefit",
"policy_snapshot": { /* full policy state at this version */ }
}]
/api/policies/{policy_id}/premiums
Get premium schedule (monthly billing dates)
[{
"id": "uuid",
"due_date": "2026-03-05",
"amount": 260.00,
"status": "PENDING|PAID|OVERDUE|CANCELLED",
"paid_date": "2026-03-03",
"payment_reference": "PAY-2026-000123"
}]
/api/policies/{policy_id}/premiums/{schedule_id}/pay
Record a premium payment
{
"org_id": "uuid",
"payment_date": "2026-03-03",
"payment_reference": "PAY-2026-000123",
"amount": 260.00
}
/api/policies/{policy_id}/premium-summary
Summary: total paid, outstanding, overdue counts
{
"monthly_premium": 260.00,
"schedule_count": 12,
"paid_count": 3,
"overdue_count": 0,
"total_paid": 780.00,
"total_outstanding": 2340.00,
"next_due_date": "2026-04-05",
"next_due_amount": 260.00
}
/api/policies/{policy_id}/transactions
Finance ledger entries (premium due/received, adjustments)
/api/policies/{policy_id}/premium-reconciliation/upload
Bulk reconciliation upload from CSV data
Baseline month-end engine for overdue marking, annual premium indexation, and lapse-candidate evaluation.
/api/month-end/process
Run month-end process (supports dry-run mode)
{
"process_date": "2026-02-28",
"dry_run": true,
"mark_overdue": true,
"apply_indexation": true,
"evaluate_lapse_candidates": true,
"auto_lapse": false,
"limit_policies": 2000
}
/api/month-end/config-preview
Preview resolved escalation rates per product at process date
Modify active policies: change cover amounts, add/remove members.
/api/policies/{policy_id}/endorse/preview
Preview premium/cover impact before submitting endorsement
/api/policies/{policy_id}/endorse
Create policy endorsement
{
"org_id": "uuid",
"endorsement_type": "CHANGE_COVER",
"policy_benefit_id": "uuid",
"new_sum_assured": 750000,
"reason": "Customer requested increase"
}
{
"org_id": "uuid",
"endorsement_type": "ADD_MEMBER",
"member_role": "SPOUSE|CHILD|PARENT|EXTENDED",
"first_name": "Jane",
"last_name": "Doe",
"date_of_birth": "1990-05-15",
"gender": "FEMALE",
"reason": "Adding spouse to policy"
}
{
"org_id": "uuid",
"endorsement_type": "REMOVE_MEMBER",
"policy_member_id": "uuid",
"reason": "Child no longer dependent"
}
Manage policy status: suspend, lapse, reinstate, cancel.
/api/policies/{policy_id}/suspend
Suspend active policy (e.g. non-payment)
{
"org_id": "uuid",
"reason": "Non-payment of premiums"
}
/api/policies/{policy_id}/lapse
Lapse policy (grace period expired)
{
"org_id": "uuid",
"reason": "Grace period expired, no payment received"
}
/api/policies/{policy_id}/reinstate
Reinstate lapsed policy
{
"org_id": "uuid",
"arrears_paid": true,
"medical_clearance": true,
"reason": "Arrears paid, medical clearance obtained"
}
/api/policies/{policy_id}/cancel
Cancel policy permanently
{
"org_id": "uuid",
"cancellation_type": "VOLUNTARY|LAPSE|NON_PAYMENT|FRAUD|OTHER",
"reason": "Customer requested cancellation"
}
Submit, assess, and pay claims with benefit-level validation and remaining cover tracking.
/api/policies/{policy_id}/claims
Submit claim with validation
{
"org_id": "uuid",
"claim_date": "2026-02-10",
"claim_type": "DEATH|DISABILITY|CRITICAL_ILLNESS|etc",
"description": "Main member accidental death",
"benefit_claims": [
{
"policy_benefit_id": "uuid",
"claimed_amount": 500000
}
]
}
{
"claim_id": "uuid",
"claim_number": "CLM-2026-000042",
"status": "SUBMITTED",
"claim_date": "2026-02-10",
"total_claimed": 500000.00,
"benefit_items": [
{
"policy_benefit_id": "uuid",
"benefit_name": "Death Benefit",
"claimed_amount": 500000.00,
"base_benefit_amount": 500000.00,
"remaining_cover": 500000.00,
"within_waiting_period": false
}
]
}
/api/claims/{claim_id}/assess
Assess claim (approve/reject per benefit)
{
"org_id": "uuid",
"benefit_assessments": [
{
"claim_benefit_item_id": "uuid",
"approved_amount": 450000, // can be partial
"decision_reason": "Approved with exclusions"
},
{
"claim_benefit_item_id": "uuid",
"approved_amount": 0, // rejected
"decision_reason": "Pre-existing condition"
}
]
}
/api/claims/{claim_id}/pay
Pay claim and deduct from remaining cover
{
"org_id": "uuid",
"payment_date": "2026-02-11",
"payment_reference": "PAY-CLM-2026-000042",
"benefit_payments": [
{
"claim_benefit_item_id": "uuid",
"paid_amount": 450000
}
]
}
// NOTE: This deducts paid_amount from policy_benefits.remaining_cover
/api/policies/{policy_id}/detail
Comprehensive policy view (one-stop for customer service)
{
"policy": { /* core policy fields */ },
"product": { "id": "uuid", "name": "Funeral Family Plan" },
"customer": { "id": "uuid", "first_name": "John", "last_name": "Doe", "email": "..." },
"members": [
{
"id": "uuid",
"role": "MAIN_MEMBER",
"first_name": "John",
"last_name": "Doe",
"date_of_birth": "1980-01-01",
"gender": "MALE",
"effective_date": "2026-02-05",
"is_active": true
}
],
"benefits": [
{
"id": "uuid",
"benefit_name": "Main Member Death",
"member_name": "John Doe",
"sum_assured": 500000.00,
"remaining_cover": 450000.00,
"status": "ACTIVE",
"waiting_period_days": 180,
"waiting_period_end_date": "2026-08-04",
"in_waiting_period": false
}
],
"premium_summary": { /* from /premium-summary endpoint */ },
"recent_events": [ /* last 10 events */ ],
"claims": [ /* all claims */ ],
"current_version": 3
}
Configure grace periods, payment reminders, and auto-reinstatement rules per product.
/api/products/{product_id}/lapse-rules
List all lapse rules for a product (ordered by effective_from DESC)
/api/products/{product_id}/lapse-rules
Create new lapse rule
{
"org_id": "uuid",
"grace_period_days": 30,
"grace_period_type": "CALENDAR",
"reminder_schedule": [7, 3, 1], // days before due date
"auto_reinstate_if_paid_within_days": 14,
"max_reinstatement_period_days": 180,
"reinstatement_requires_medical_after_days": 90,
"monthly_grace_days": 30,
"quarterly_grace_days": 45,
"annual_grace_days": 60,
"send_sms_reminders": true,
"send_email_reminders": true,
"effective_from": "2026-01-01"
}
/api/lapse-rules/{rule_id}
Update existing lapse rule
/api/dashboard
Get dashboard statistics
{
"products": 4,
"active_products": 3,
"customers": 2,
"quotes": 1,
"policies": 3,
"active_policies": 3,
"total_monthly_premium": 810.00,
"total_cover": 1100000.00
}
Click on a table to view its structure and data. Lines show foreign key relationships.