Skip to content

Analytics

The @openinsure/analytics package provides portfolio KPI computation, Workers AI-powered predictive modeling, AI cost anomaly detection, and event tracking via Tinybird. It is consumed by the API worker’s analytics routes and by the Finance/Carrier portals.

computeMGAKPIs(policies, claims, submissions)

Section titled “computeMGAKPIs(policies, claims, submissions)”

Computes the full MGA portfolio metrics snapshot:

const kpis = computeMGAKPIs(policies, claims, submissions);
// Returns: MGAPortfolioKPIs

Output:

FieldDescription
grossWrittenPremiumSum of grossPremium across active/issued/renewed policies
earnedPremiumGWP × 0.85 (earned premium factor)
totalIncurredSum of paidAmount + reserveAmount across all claims
lossRatiototalIncurred / earnedPremium
expenseRatio12% of earned premium (MGA default)
combinedRatiolossRatio + expenseRatio
gwpByLobGWP breakdown by line of business
gwpByStateGWP breakdown by state
submissionCountTotal submissions in pipeline
boundRateSubmissions with status = 'bound' / total
producerRankingsTop producers by GWP contribution

computeCaptiveKPIs(policies, claims, members)

Section titled “computeCaptiveKPIs(policies, claims, members)”

Captive-specific fund analysis:

FieldDescription
fundBalanceNet fund position
memberContributionsTotal premium contributions
claimReservesActive claim reserve total
ibnrEstimateCase reserves × 15%
stopLossPenetrationsMembers approaching specific stop-loss attachment
premiumToSurplusRatioRegulatory solvency indicator

Claims summary for dashboard widgets:

const summary = summarizeClaims(claims);
// { openCount, closedCount, totalPaid, totalReserved, totalIncurred, avgCycleTimeDays, ibnrEstimate }

computeSubmissionPipelineKPIs(submissions)

Section titled “computeSubmissionPipelineKPIs(submissions)”

Submission funnel metrics:

const pipeline = computeSubmissionPipelineKPIs(submissions);
// { inQueue, autoAccepted, autoReferred, autoDeclined, avgAppetiteScore, premiumIndicated }

Workers AI-powered financial forecasting. Calls the CF Workers AI binding with a structured JSON schema for deterministic output.

predictLossRatio(input: LossRatioPredictionInput)

Section titled “predictLossRatio(input: LossRatioPredictionInput)”

Forecasts loss ratio for a given LOB using historical performance and macro factors:

const forecast = await predictLossRatio(
{
lineOfBusiness: 'Commercial Auto',
historicalLossRatios: [0.62, 0.58, 0.71, 0.65], // prior 4 years
premiumTrend: 0.08, // 8% premium growth
claimFrequencyTrend: 0.03, // 3% frequency increase
macroFactors: {
inflation: 0.04,
socialInflation: 0.06,
economicCycle: 'expansion',
},
},
aiBinding
);
// Returns: LossRatioPrediction
// { forecastLossRatio, lowerBound90, upperBound90, trend, keyDrivers[] }

scorePricingAdequacy(currentPremium, predictedLossRatio, expenses)

Section titled “scorePricingAdequacy(currentPremium, predictedLossRatio, expenses)”

Evaluates whether current pricing is adequate:

const adequacy = scorePricingAdequacy(1_200, 0.68, 0.15);
// { adequate: false, score: 42, deficiencyPercent: 0.17, recommendedAdjustment: 1.24 }

Retention & Portfolio Health (predictive.ts)

Section titled “Retention & Portfolio Health (predictive.ts)”

scoreRetention(policy, claims, paymentHistory)

Section titled “scoreRetention(policy, claims, paymentHistory)”

Predicts renewal retention risk:

const score = scoreRetention(policy, claims, payments);
// { score: 78, riskLevel: 'medium', factors: ['3 claims this term', 'premium increase > 15%'] }

Risk levels: low (80+) · medium (60–79) · high (40–59) · critical (<40)

findCrossSellopportunities(insured, policies)

Section titled “findCrossSellopportunities(insured, policies)”

Identifies cross-sell opportunities based on current coverages and industry:

const opps = findCrossSellOpportunities(insured, activePolicies);
// [{ recommendedLob: 'Cyber', estimatedPremium: 4800, priority: 'high', reasoning: '...' }]

Premium factors by LOB: GL 1.0× · WC 1.2× · BOP 0.8× · Commercial Auto 1.1× · Cyber 2.2×

Portfolio concentration and at-risk premium analysis:

const health = computePortfolioHealth(policies);
// { concentrationIndex, topLobs, topStates, atRiskPremium, herfindahlIndex }

herfindahlIndex > 0.25 signals dangerous concentration in a single LOB or state.

detectSpendAnomaly(dailyCosts, multiplier?)

Section titled “detectSpendAnomaly(dailyCosts, multiplier?)”

Detects AI API cost spikes using a rolling 7-day average:

const result = detectSpendAnomaly(last30Days, 3.0);
// { isAnomaly: true, currentCost: 142.50, avgCost: 38.20, ratio: 3.73 }

Default multiplier is 3.0 — anything 3× the rolling average triggers an anomaly alert. Used by the cron job (apps/api/src/cron/portfolio-sweep.ts) to emit a queue event when AI costs spike.

import { trackEvent } from '@openinsure/analytics';
await trackEvent(
'submission.quoted',
{
submissionId: 'sub_123',
orgId: 'org_456',
premium: 12500,
lineOfBusiness: 'GL',
state: 'NC',
},
env.ANALYTICS_ENGINE
);

Events flow to Tinybird via Cloudflare Analytics Engine. The ANALYTICS_ENGINE binding is configured in wrangler.toml under [analytics_engine_datasets].

For high-throughput events (policy bound, claim opened, payment processed), the API writes directly to the CF Analytics Engine binding — zero latency, no HTTP call:

env.ANALYTICS_ENGINE.writeDataPoint({
blobs: [submissionId, orgId, lob, state],
doubles: [premium, claimCount, reserveAmount],
indexes: [orgId],
});

The analytics package powers these API endpoints:

RouteDescription
GET /v1/analytics/mgaMGA portfolio KPIs
GET /v1/analytics/captiveCaptive fund KPIs
GET /v1/analytics/pipelineSubmission funnel metrics
GET /v1/analytics/entitiesEntity-level analytics
GET /v1/analytics/complianceFiling status breakdown
GET /v1/analytics/claimsClaims frequency and severity

All routes accept ?period=ytd|qtd|mtd and ?orgId= filters.

Extend compute.ts by adding a new function:

export function computeMyKPI(data: MyData): MyKPIResult {
// deterministic calculation — no side effects
return { ... };
}

Add the corresponding API route in apps/api/src/routes/analytics.ts and update the Tinybird datasource schema if new event types are needed.

Finance Portal

AR aging, statutory reports, and TigerBeetle ledger.

AI Agents

Predictive underwriting and claims AI agents.