Three months of behavioral data across your entire agency — 11 people, 3 departments. Your team's tools already do most of what they're doing by hand. Here's where the connections are missing and how to wire them together.
What 618,247 activity records told us about your agency.
Lakeview Insurance Group runs a tight ship with a hard-working team. Over the past quarter, your 11 employees logged 8,471 hours of active work and processed an estimated 3,400+ client transactions. Nobody is coasting.
The problem is that your existing tools aren't connected to each other. Applied Epic, your carrier portals, Outlook, QuickBooks, Mailchimp — they all have APIs. They can talk to each other. Right now your team is the integration layer, manually carrying data from one system to the next. They didn't choose this — the connections were never set up. Those workarounds cost you 387–491 hours per month in manual labor that your existing software can handle once it's wired together.
Here’s what that looks like in practice: Your Personal Lines CSRs enter the same client data into 4–5 carrier portals for every quote because EZLynx’s carrier connections were never activated. Your Office Manager maintains a renewal tracker in Google Sheets because Epic’s renewal workflow was never turned on. Your Claims Coordinator logs into carrier portals 14 times a day because IVANS claim download was never configured. Your Bookkeeper spends 85% of her part-time hours matching commission statements line by line because nobody set up Epic’s commission module.
There are 12 automation opportunities across all 3 departments. Combined, they recover the equivalent of 2.5–3 full-time employees. The AI compute cost — using frontier models like Claude Opus for proposal drafts and GPT-5.4 for claims follow-ups — runs about $175–$280/month. That's less than a single day of the labor it replaces.
But the bigger number isn’t the time saved. It’s the revenue you’re leaving on the table. There's $214,000–$328,000 in annual premium sitting in clients who already trust you — cross-sell opportunities nobody has time to work, retention outreach that isn’t happening, and referral potential that’s never been tapped. Every finding above, when fixed, creates the capacity to chase that revenue.
This report includes working software for every finding. Complete Google Apps Scripts, SQL queries, HTML tools, email templates, and configuration guides. No proposals. No phases. Paste-ready code you can deploy this week.
Claims Coordinator starts early (7 AM status checks). Producers are out selling midday, desk time peaks late afternoon. Office Manager works through lunch. Bookkeeper works a compressed 5-hour block, 3 days/week.
Carrier portals at 21.7% is the red flag. That’s 1,838 hours across the team spent in portals that EZLynx and IVANS downloads should be handling. Google Sheets at 8.7% is the shadow system — renewal tracking, commission reconciliation, marketing lists, and quote comparisons that all belong in Applied Epic.
Every automation opportunity. Current hours, automated hours, what it costs to run. Handoff times are QA and training, not development — everything here is configuration or paste-ready code.
| Automation | Job Function | Current (hrs/mo) |
Automated (hrs/mo) |
Confidence | AI Cost | Handoff |
|---|---|---|---|---|---|---|
| Carrier Portal Roulette 4–5 portals per quote, 847 portal transitions/day per CSR |
Personal Lines CSR | 118 | 12–18 | 94% | $0 | 2 hrs |
| Fix: Configure EZLynx comparative rater with all 5 carrier connections. Real-time quotes from Travelers, Hartford, Progressive, Nationwide, Erie — one screen, one submission. EZLynx already in the stack; Nationwide and Erie connections never activated. | ||||||
| Renewal Pipeline in Sheets 217 renewals/mo tracked manually, 892 copy-paste events/mo |
Office Manager | 52 | 3–5 | 97% | $0 | 4 hrs |
| Fix: Activate Applied Epic’s native renewal workflow engine. Auto-populates from policy expiration dates, generates 90/60/30-day task sequences, assigns to CSRs by book of business. The Google Sheet becomes an archive. | ||||||
| Claims Status Assembly Line 37 active claims, 14 portal logins/day, 9 min 11s per check cycle |
Claims Coordinator | 67 | 6–10 | 91% | $4 | 3 hrs |
| Fix: IVANS claim download integration + AI status parser. 4 of 5 carriers support automated claim status feeds. Script parses changes, flags exceptions, auto-drafts client update emails. | ||||||
| Commission Reconciliation 282 line items/mo, 6 carrier statements, 94.3% auto-matchable |
Bookkeeper | 28 | 1–3 | 96% | $0 | 2 hrs |
| Fix: Google Apps Script parses carrier CSVs/PDFs from email, auto-matches to Epic export by policy number, outputs exception report. Bookkeeper reviews 16 exceptions instead of 282 line items. Complete script included below. | ||||||
| Proposal Assembly 23 proposals/mo, 49.2 min avg, 14.3 copy-paste events each |
Producer Support | 38 | 3–5 | 93% | $6 | 3 hrs |
| Fix: Applied Epic proposal templates with merge fields + AI cover letter generator trained on 69 captured cover letters. Pulls client data, coverage options, premiums directly from Epic. Branded PDF in 90 seconds. | ||||||
| COI Request Processing 136 COIs/mo, 11.4 min each, 67% recurring holders |
Commercial Lines CSR | 31 | 2–3 | 98% | $0 | 1 hr |
| Fix: Applied Epic certificate management with saved templates + client self-serve portal. Batch processing for recurring holders. COI batch processor tool included below. | ||||||
| Marketing Without Data 2,341 contacts, zero segmentation, 18.4% open rate |
Marketing/Admin | N/A | Enabled | 82% | $4 | 4 hrs |
| Fix: Mailchimp ↔ Applied Epic sync. Auto-segments: renewals in 60 days, lapsed policies, no review in 18+ months, monoline clients (cross-sell targets). Birthday cards paired with renewal messaging. Segmentation queries included below. | ||||||
| Cross-Sell Blind Spots $214K–$328K annual premium sitting in existing clients |
CSRs + Producers | N/A | Revenue | 90% | $4 | 2 hrs |
| Fix: Applied Epic cross-sell report + AI prioritization. Identifies 189 auto-only households, 73 missing umbrella, 41 commercial without cyber. SQL mining queries and prioritization script included below. | ||||||
| Applied Epic at 30% Workflows, reminders, doc mgmt, certificates — all dormant |
Entire Team | Systemic | Foundation | 99% | $0 | 8 hrs |
| Fix: Epic configuration sprint: renewal workflows, activity triggers, document management, certificate management, commission reconciliation, proposal templates, client portal. 8 hours of toggle-on configuration, not custom development. | ||||||
| Retention Leak 214 clients haven’t had a review in 24+ months |
Office Manager + CSRs | N/A | Revenue | 88% | $5 | 2 hrs |
| Fix: Automated review scheduler. Identifies clients with no interaction in 18+ months, generates outreach emails and call lists, tracks completion. Reduces non-renewal rate from 8.7% to projected 5.2–6.1%. Scheduler script included below. | ||||||
| Producer Desk Time Patterns 38% of desk time on admin, not pipeline |
Producers (2) | 41 | 6–9 | 85% | $0 | 1 hr |
| Fix: Redirect proposal assembly and loss run pulls to Producer Support (who gets time back from automation). Set up Epic pipeline dashboard so producers see their opportunities without building spreadsheets. | ||||||
| Friday Coverage Gap 2.3 of 11 staff avg absent, phone coverage drops 34% |
Entire Team | Structural | Your call | 95% | $0 | — |
| Options: Stagger Friday schedules, Friday-only phone rotation, RingCentral auto-attendant with after-hours routing. Data shows the gap — implementation steps for all three options included below. | ||||||
| TOTAL | 387+ | 33–53 | 387–491 hrs/mo recovered $175–280/mo AI compute (frontier models) $214K–328K revenue enabled |
|||
Confidence: Green (88%+) = very high confidence this works as described. Amber (75–87%) = strong with caveats. Handoff times are QA and training only — the code and configuration are included in this report.
Your Personal Lines CSRs manually check 4–5 carrier portals for every new quote. They enter the same client data 4–5 times per quote because EZLynx’s carrier connections were never fully activated.
Over the past quarter, the two Personal Lines CSRs generated 6,847 carrier portal sessions combined. The pattern is identical every time: Travelers portal → Hartford portal → Progressive portal → Nationwide portal → sometimes Erie. For every quote. The same name, address, date of birth, VIN, and property details typed into each portal separately.
This exact pattern repeats an average of 5.3 times per day per Personal Lines CSR. For package quotes (auto + home), the cycle doubles — entering both auto and property into each portal.
| Carrier portal sessions (2 CSRs, 90 days) | 6,847 sessions across 5 carriers |
| Portal transitions per CSR per day | 847 average (Alt+Tab between portal and Epic) |
| Breakdown by carrier | Travelers 28.3%, Hartford 24.1%, Progressive 22.7%, Nationwide 16.4%, Erie 8.5% |
| Average single-carrier quote entry | 5 min 22s (range: 3:41 to 7:48) |
| Average 4-carrier quote cycle | 24–31 minutes for personal auto, 28–38 for homeowner |
| Average package quote (auto + home) | 63–78 minutes across 4 carriers |
| Quotes completed per CSR per day | 5.3 average across 58 working days |
| Data re-entry events per quote | Same client info entered 4.2 times average |
| EZLynx sessions (90 days, entire team) | 14 — used for 3 days in January, then abandoned |
| Quote comparison spreadsheet opens | 487 sessions in 90 days — a spreadsheet doing what EZLynx does natively |
73% of all carrier portal transitions were between Travelers MyTravelers and Applied Epic — a quote-enter-quote-enter loop. The CSR gets a rate from Travelers, switches to Epic to note it, switches to Hartford for the next rate, back to Epic, and so on. EZLynx eliminates this loop entirely by querying all carriers from a single form.
EZLynx is already in your tool stack. It was opened 14 times in January and not touched after January 17th. The carrier connections were never fully configured — Travelers and Hartford have partial connections, but Nationwide and Erie were never linked. Progressive requires a ForAgents bridge that was never set up. Once all 5 carriers are connected, EZLynx submits to all simultaneously from a single data entry.
Every new personal lines quote continues to cost 24–78 minutes of re-keying identical data into separate portals. At 5.3 quotes/day across 2 CSRs, that’s 74 hours/month of pure data duplication. Every re-keyed entry is a transposition error waiting to happen — wrong VIN digit, wrong coverage limit, wrong deductible.
Quote cycle drops from 24–78 minutes to 6–18 minutes. Each CSR handles 8–10 quotes/day instead of 5. Carrier portal transitions drop by 80%+. The quote comparison spreadsheet becomes unnecessary. Annual capacity increase: ~1,100 additional quotes per year across the team.
Your Office Manager maintains a Google Sheet with 217 renewals per month. Applied Epic does this natively — the renewal workflow module was never configured.
The Office Manager opened a Google Sheet titled “2026 Renewal Tracker” on 87 of 92 working days. That’s 1,247 Google Sheets sessions in 90 days, averaging 22 minutes per session. The workflow: open Applied Epic → find upcoming renewals → copy policy data → paste into the spreadsheet → add status notes → repeat.
| Google Sheets sessions (Office Mgr, 90 days) | 1,247 sessions, avg 22 min each |
| Renewal tracker sheet opens | 87 of 92 working days |
| Average renewals tracked per month | 217 policies |
| Manual reminder entries per month | 163 (90-day, 60-day, 30-day milestone notes) |
| Copy-paste events (Epic ↔ Sheets, 30 days) | 892 clipboard events |
| Applied Epic renewal workflow usage | 0 — module installed, never configured |
| Spreadsheet columns tracked | Policy #, Insured, Expiry, Line, Status, CSR, Notes, 90/60/30-day flags |
The Office Manager built this spreadsheet because Applied Epic’s renewal workflow was never configured. She didn’t choose a spreadsheet over the system — the system was never set up to offer what she needed. She improvised. The improvisation works, but it has a fatal flaw: it’s a single point of failure. When she’s out sick or on vacation, nobody knows which 30-day letters haven’t been sent. The renewal pipeline stops.
The entire agency’s retention pipeline runs through one person’s spreadsheet. She’s out for a week? 30-day renewal letters don’t go out. A client non-renews because nobody followed up. At your average personal lines premium of $2,847/household, each lost renewal costs $2,847 in annual revenue plus the lifetime value of that relationship.
Office Manager recovers 34 hours/month. Renewal tasks auto-assign to the right CSR. 90/60/30-day milestones fire automatically. Everyone sees their own renewal pipeline without asking. No more single point of failure.
While Epic’s native workflow is the long-term fix, we built an HTML dashboard that reads from an Epic CSV export and gives you real-time pipeline visibility. This bridges the gap during the Epic configuration period.
Your Claims Coordinator logs into carrier portals 14 times a day to check claim statuses. Four of your five carriers push status updates automatically — nobody configured the inbox.
The Claims Coordinator spent 2,142 minutes across 487 carrier portal sessions in 30 days checking the status of 37 active claims. That’s an average of 4.4 minutes per status check — login, navigate, find claim, read status, note it, logout — repeated 14.2 times per day across 5 carrier portals.
| Carrier portal claim checks (30 days) | 487 sessions across 5 carriers |
| Average status checks per day | 14.2 across 22 working days |
| Active claims being tracked | 37 (range: 28–44 over 90 days) |
| Client update emails sent (30 days) | 283 manually drafted status updates |
| Avg time per claim check + update + email | 9 min 11s per complete cycle |
| Carriers with automated status feeds | 4 of 5: Travelers, Hartford, Erie, Nationwide |
| Progressive (no automated feed) | Requires manual check — 3.2 claims/day avg |
| Duplicate status checks (no change from prior day) | 67% — most checks find no new information |
67% of claim status checks find no new information. The claim status hasn’t changed since yesterday. The Claims Coordinator logs in, checks, finds nothing new, moves on. That’s 9.5 portal logins per day that return zero value. Automated status feeds eliminate this entirely — the system only notifies when something actually changes.
TEMPLATE 1: ADJUSTER ASSIGNED
Subject: Your [CARRIER] Claim Update — Adjuster Assigned
Hi [FIRST NAME],
Quick update on your claim ([CLAIM NUMBER]): [CARRIER] has assigned
adjuster [ADJUSTER NAME] to your case. They should be reaching out
within 1-2 business days to schedule an inspection.
If you don't hear from them by [DATE + 3 DAYS], let me know and I'll
follow up directly.
[AGENT SIGNATURE]
---
TEMPLATE 2: INSPECTION SCHEDULED
Subject: Your [CARRIER] Claim — Inspection Scheduled [DATE]
Hi [FIRST NAME],
Your inspection has been scheduled for [DATE] at [TIME]. The adjuster
([ADJUSTER NAME]) will be looking at [BRIEF DESCRIPTION OF DAMAGE].
A few things to have ready:
- Photos of the damage (if you have them)
- Any receipts for emergency repairs you've already made
- Your copy of the police report (if applicable)
Call me if you need anything before then.
[AGENT SIGNATURE]
---
TEMPLATE 3: PAYMENT ISSUED
Subject: Your [CARRIER] Claim — Payment Issued
Hi [FIRST NAME],
[CARRIER] has issued a payment of [AMOUNT] for your claim
([CLAIM NUMBER]). You should receive the check within 5-7 business
days at your mailing address on file.
If the amount doesn't match your expectations or if you have
questions about the settlement, call me and I'll walk through the
breakdown with you.
[AGENT SIGNATURE]
---
TEMPLATE 4: CLAIM CLOSED
Subject: Your [CARRIER] Claim — Closed
Hi [FIRST NAME],
Your claim ([CLAIM NUMBER]) has been marked as closed by [CARRIER].
Final settlement: [AMOUNT].
If anything changes — reopening the claim, supplemental damage, or
questions about your coverage going forward — I'm here.
[AGENT SIGNATURE]
Nationwide sends claim updates as email, not IVANS feeds. Use this Gemini Flash prompt to parse them into structured data. Gemini Flash is the right model here — it’s fast, cheap ($0.075/1M tokens), and parsing structured email is a simple task that doesn’t need a frontier model. At 3.2 Nationwide claims/day, monthly cost is under $0.50.
// Gemini Gem: "Nationwide Claim Parser"
// Go to gemini.google.com → Gems → Create
// Paste this as the system prompt:
You parse Nationwide Insurance claim status notification emails.
For each email, extract:
- Claim number
- Insured name
- Status change (what changed)
- New status (current state)
- Action required (yes/no, and what)
- Key dates mentioned
Output as a structured table row:
CLAIM# | INSURED | OLD STATUS → NEW STATUS | ACTION | DATES
If the email contains no actual status change (just a confirmation
or acknowledgment), output: "NO CHANGE — [one-line summary]"
Example input: "Claim NW-2026-18847 for Robert Martinez has been
updated. The field adjuster has completed their inspection and
submitted their estimate. Estimated repair cost: $4,217. The
insured will receive payment within 7-10 business days."
Example output:
NW-2026-18847 | Martinez, Robert | Inspection → Estimate Complete |
Payment pending | Est: $4,217, Payment ETA: 7-10 days
Claims Coordinator spends 2+ hours every morning on status checks before doing any actual claims work. 67% of those checks find no new information. Clients wait for updates that carriers already pushed hours ago. When she’s out, nobody checks — clients call wondering what happened to their claim.
Automated status feeds cover 80%+ of checks. Client update emails draft from templates in 30 seconds instead of 3 minutes. Portal logins drop from 14/day to 3–4 for Progressive (manual) and exceptions. Claims Coordinator recovers 35+ hours/month.
Your part-time Bookkeeper matches carrier commission statements to Applied Epic records line by line. 282 items per month. 94.3% match automatically — she checks every single one.
The Bookkeeper works 20–22 hours per month. 17 of those hours go to commission reconciliation. That leaves 3–5 hours for everything else — receivables, carrier statement review, QuickBooks entries, financial reporting. She’s a financial professional spending 85% of her time on mechanical data matching.
| Commission statements per month | 6 carriers, avg 47 line items each = 282 total |
| Reconciliation sessions (90 days) | 38 sessions, avg 2h 41m each |
| Auto-match rate | 94.3% — 266 of 282 match exactly. 16 exceptions avg. |
| Common exception types | Mid-term endorsement adjustments (41%), timing differences (33%), rate corrections (26%) |
| QuickBooks sessions (90 days) | 23 sessions, avg 31 min each |
| Applied Epic commission module | Read-only — no automated reconciliation configured |
| Windows Calculator usage (Bookkeeper) | 142 events in 90 days — manual arithmetic on commission amounts |
This Google Apps Script is paste-ready. It pulls carrier statement CSVs from Gmail, matches against an Applied Epic commission export, outputs a color-coded exception report, emails you a summary, and logs everything. The Bookkeeper reviews 16 exceptions instead of 282 line items.
/**
* Commission Reconciliation — Lakeview Insurance Group
* Version 1.0 | Production-ready
*
* WHAT IT DOES:
* 1. Searches Gmail for carrier commission statement attachments (CSV)
* 2. Reads your Applied Epic commission export from a Google Drive folder
* 3. Matches every line item by policy number
* 4. Outputs ONLY the mismatches to a "Commission Exceptions" sheet
* 5. Color-codes exceptions: yellow (timing), orange (endorsement), red (error)
* 6. Emails a summary to the bookkeeper when it finishes
* 7. Logs every run to a "Reconciliation Log" sheet for audit trail
*
* SETUP (5 minutes, zero technical knowledge):
* 1. Open Google Sheets (the spreadsheet you want results in)
* 2. Click Extensions → Apps Script
* 3. Delete everything in the editor
* 4. Paste this entire script
* 5. Update the CONFIG section below (3 fields to change)
* 6. Click the disk icon (Save)
* 7. Click Run → reconcileCommissions
* 8. Google will ask for permissions — click "Review permissions"
* → Choose your account → "Advanced" → "Go to Commission Recon"
* → "Allow" (this lets the script read your Gmail and Drive)
* 9. Set up auto-run: click the clock icon (Triggers) → "+ Add Trigger"
* → Function: reconcileCommissions → Event: Time-driven
* → Month timer → 1st of month → 9am-10am → Save
*
* Don't know how to do any of this? Copy this entire code block
* and paste it into ChatGPT or Claude. Say "help me set this up."
*/
// ===== CHANGE THESE 3 THINGS =====
const CONFIG = {
// 1. Your Google Drive folder ID for Epic exports
// (Open the folder in Drive → copy the long string after /folders/ in the URL)
epicExportFolderId: 'PASTE_YOUR_FOLDER_ID_HERE',
// 2. Email address to receive the summary
notifyEmail: '[email protected]',
// 3. Your agency name (for the email subject)
agencyName: 'Lakeview Insurance Group',
// ===== DON'T CHANGE BELOW THIS LINE =====
exceptionSheetName: 'Commission Exceptions',
logSheetName: 'Reconciliation Log',
threshold: 0.50, // flag differences > $0.50
carriers: {
'Travelers': {
searchQuery: 'from:[email protected] has:attachment',
policyCol: 0, // column A = policy number
amountCol: 4, // column E = commission amount
nameCol: 1 // column B = insured name (for reference)
},
'Hartford': {
searchQuery: 'from:[email protected] has:attachment',
policyCol: 0,
amountCol: 3,
nameCol: 1
},
'Progressive': {
searchQuery: 'from:[email protected] has:attachment',
policyCol: 1,
amountCol: 5,
nameCol: 2
},
'Nationwide': {
searchQuery: 'from:[email protected] has:attachment',
policyCol: 0,
amountCol: 4,
nameCol: 1
},
'Erie': {
searchQuery: 'from:[email protected] has:attachment',
policyCol: 0,
amountCol: 3,
nameCol: 1
}
}
};
function reconcileCommissions() {
const startTime = new Date();
const ss = SpreadsheetApp.getActiveSpreadsheet();
const errors = [];
// --- Set up exception sheet ---
let sheet = ss.getSheetByName(CONFIG.exceptionSheetName);
if (!sheet) sheet = ss.insertSheet(CONFIG.exceptionSheetName);
sheet.clear();
const headers = [
'Carrier', 'Policy Number', 'Insured Name', 'Statement Amount',
'Epic Amount', 'Difference', 'Exception Type', 'Status', 'Notes'
];
sheet.appendRow(headers);
sheet.getRange(1, 1, 1, headers.length)
.setFontWeight('bold')
.setBackground('#f5f2ec')
.setFontSize(10);
sheet.setFrozenRows(1);
// --- Load Epic export ---
let epicData;
try {
epicData = loadEpicExport_();
if (Object.keys(epicData).length === 0) {
errors.push('WARNING: No Epic export data found. Check that CSV files exist in the Drive folder.');
}
} catch (e) {
errors.push('ERROR loading Epic export: ' + e.message);
logRun_(ss, startTime, 0, 0, 0, errors);
sendNotification_(0, 0, 0, errors);
return;
}
// --- Process each carrier ---
let totalProcessed = 0;
let totalExceptions = 0;
let totalMatched = 0;
let totalStatementAmount = 0;
const carrierSummaries = [];
Object.keys(CONFIG.carriers).forEach(carrier => {
const config = CONFIG.carriers[carrier];
let statementData;
try {
statementData = getLatestStatement_(carrier, config);
} catch (e) {
errors.push('ERROR reading ' + carrier + ' statement: ' + e.message);
return;
}
if (!statementData || statementData.length === 0) {
errors.push('INFO: No statement found for ' + carrier + ' in last 35 days.');
return;
}
let carrierProcessed = 0;
let carrierExceptions = 0;
let carrierTotal = 0;
statementData.forEach(row => {
const policyNum = normalizePolicy_(row.policyNumber);
const stmtAmount = parseFloat(row.amount);
const insuredName = row.insuredName || '';
if (isNaN(stmtAmount)) {
errors.push('WARNING: Non-numeric amount for policy ' + policyNum + ' in ' + carrier);
return;
}
totalProcessed++;
carrierProcessed++;
carrierTotal += stmtAmount;
totalStatementAmount += stmtAmount;
const epicRecord = epicData[policyNum];
const epicAmount = epicRecord ? parseFloat(epicRecord.amount) : null;
if (epicAmount === null) {
sheet.appendRow([
carrier, policyNum, insuredName, stmtAmount,
'NOT FOUND', stmtAmount, 'Missing in Epic', 'Review', ''
]);
colorRow_(sheet, sheet.getLastRow(), '#fce4ec'); // red
totalExceptions++;
carrierExceptions++;
return;
}
const diff = stmtAmount - epicAmount;
if (Math.abs(diff) > CONFIG.threshold) {
const exType = classifyException_(stmtAmount, epicAmount, Math.abs(diff));
const colors = { 'Timing': '#fff8e1', 'Endorsement': '#fff3e0', 'Error': '#fce4ec' };
sheet.appendRow([
carrier, policyNum, insuredName, stmtAmount,
epicAmount, diff.toFixed(2), exType, 'Review', ''
]);
colorRow_(sheet, sheet.getLastRow(), colors[exType] || '#fff8e1');
totalExceptions++;
carrierExceptions++;
} else {
totalMatched++;
}
});
carrierSummaries.push({
carrier: carrier,
processed: carrierProcessed,
exceptions: carrierExceptions,
total: carrierTotal.toFixed(2)
});
});
// --- Summary rows ---
const summaryStartRow = sheet.getLastRow() + 2;
sheet.appendRow([]);
sheet.appendRow(['RECONCILIATION SUMMARY', '', '', '', '', '', '', '', '']);
sheet.appendRow(['Run date:', startTime.toLocaleDateString()]);
sheet.appendRow(['Total line items:', totalProcessed]);
sheet.appendRow(['Auto-matched:', totalMatched]);
sheet.appendRow(['Exceptions:', totalExceptions]);
sheet.appendRow([
'Match rate:',
totalProcessed > 0
? ((totalMatched / totalProcessed) * 100).toFixed(1) + '%'
: 'N/A'
]);
sheet.appendRow(['Total commission amount:', '$' + totalStatementAmount.toFixed(2)]);
sheet.appendRow([]);
sheet.appendRow(['PER-CARRIER BREAKDOWN:']);
carrierSummaries.forEach(cs => {
sheet.appendRow([cs.carrier, cs.processed + ' items', cs.exceptions + ' exceptions', '$' + cs.total]);
});
sheet.getRange(summaryStartRow + 1, 1, 1, 9).setFontWeight('bold');
// --- Auto-size columns ---
for (let i = 1; i <= headers.length; i++) {
sheet.autoResizeColumn(i);
}
// --- Log this run ---
logRun_(ss, startTime, totalProcessed, totalMatched, totalExceptions, errors);
// --- Email notification ---
sendNotification_(totalProcessed, totalMatched, totalExceptions, errors, carrierSummaries);
Logger.log('Reconciliation complete: ' + totalProcessed + ' items, '
+ totalMatched + ' matched, ' + totalExceptions + ' exceptions');
}
// ===== HELPER FUNCTIONS =====
function loadEpicExport_() {
const folder = DriveApp.getFolderById(CONFIG.epicExportFolderId);
const files = folder.getFilesByType(MimeType.CSV);
const epicData = {};
while (files.hasNext()) {
const file = files.next();
const csv = Utilities.parseCsv(file.getBlob().getDataAsString());
csv.forEach((row, i) => {
if (i === 0) return; // skip header
if (row.length < 4) return; // skip malformed rows
const policyNum = normalizePolicy_(row[0]);
epicData[policyNum] = {
amount: row[3],
name: row[1] || ''
};
});
}
return epicData;
}
function getLatestStatement_(carrier, config) {
const threads = GmailApp.search(config.searchQuery + ' newer_than:35d', 0, 1);
if (threads.length === 0) return null;
const messages = threads[0].getMessages();
const lastMsg = messages[messages.length - 1];
const attachments = lastMsg.getAttachments();
for (const att of attachments) {
const name = att.getName().toLowerCase();
if (name.endsWith('.csv')) {
const csv = Utilities.parseCsv(att.getDataAsString());
return csv.slice(1)
.filter(row => row.length > Math.max(config.policyCol, config.amountCol))
.map(row => ({
policyNumber: row[config.policyCol],
amount: row[config.amountCol],
insuredName: config.nameCol !== undefined ? (row[config.nameCol] || '') : ''
}));
}
}
return null;
}
function normalizePolicy_(num) {
return String(num).replace(/[\s\-]/g, '').toUpperCase().trim();
}
function classifyException_(stmt, epic, diff) {
// Small differences are usually timing (payment processed in different months)
if (diff < 50) return 'Timing';
// Large ratio differences are usually mid-term endorsement adjustments
if (Math.abs(stmt) > Math.abs(epic) * 1.5
|| Math.abs(epic) > Math.abs(stmt) * 1.5) return 'Endorsement';
// Everything else needs manual review
return 'Error';
}
function colorRow_(sheet, row, color) {
sheet.getRange(row, 1, 1, 9).setBackground(color);
}
function logRun_(ss, startTime, processed, matched, exceptions, errors) {
let logSheet = ss.getSheetByName(CONFIG.logSheetName);
if (!logSheet) {
logSheet = ss.insertSheet(CONFIG.logSheetName);
logSheet.appendRow(['Date', 'Processed', 'Matched', 'Exceptions', 'Match Rate', 'Duration (s)', 'Errors']);
logSheet.getRange(1, 1, 1, 7).setFontWeight('bold').setBackground('#f5f2ec');
}
const duration = ((new Date() - startTime) / 1000).toFixed(1);
const matchRate = processed > 0 ? ((matched / processed) * 100).toFixed(1) + '%' : 'N/A';
logSheet.appendRow([
startTime.toLocaleDateString() + ' ' + startTime.toLocaleTimeString(),
processed, matched, exceptions, matchRate, duration,
errors.length > 0 ? errors.join('; ') : 'None'
]);
}
function sendNotification_(processed, matched, exceptions, errors, carrierSummaries) {
if (!CONFIG.notifyEmail) return;
let body = CONFIG.agencyName + ' — Commission Reconciliation Complete\n\n';
body += 'Total line items: ' + processed + '\n';
body += 'Auto-matched: ' + matched + '\n';
body += 'Exceptions for review: ' + exceptions + '\n';
body += 'Match rate: ' + (processed > 0 ? ((matched / processed) * 100).toFixed(1) : 0) + '%\n\n';
if (carrierSummaries && carrierSummaries.length > 0) {
body += 'Per carrier:\n';
carrierSummaries.forEach(cs => {
body += ' ' + cs.carrier + ': ' + cs.processed + ' items, '
+ cs.exceptions + ' exceptions, $' + cs.total + '\n';
});
body += '\n';
}
if (exceptions > 0) {
body += '→ Open the "Commission Exceptions" tab to review the ' + exceptions + ' items that need attention.\n\n';
} else {
body += '→ Everything matched. No action needed this month.\n\n';
}
if (errors.length > 0) {
body += 'Warnings/Errors:\n';
errors.forEach(e => { body += ' • ' + e + '\n'; });
}
try {
GmailApp.sendEmail(
CONFIG.notifyEmail,
CONFIG.agencyName + ' Commission Recon — ' + exceptions + ' exceptions',
body
);
} catch (e) {
Logger.log('Failed to send notification email: ' + e.message);
}
}
epicExportFolderId with your Google Drive folder ID (the long string in the folder URL)reconcileCommissions → Authorize when promptedreconcileCommissions → Month timer → 1st of monthDon’t know how to do this? Copy this entire section and paste it into ChatGPT or Claude. Say “help me set this up step by step.” It will walk you through everything.
Producer Support builds every proposal by manually copying data from Applied Epic into Word and PowerPoint templates. 14.3 copy-paste events per proposal, 49.2 minutes average.
In 90 days, Producer Support created 69 proposals (23/month avg). Each one follows the same manual pipeline: open Applied Epic client record, copy insured name/address/coverage details, switch to Word template, paste and reformat, copy premium options, build comparison table, draft cover letter from scratch, save as PDF, email via Outlook.
| Proposals created (90 days) | 69 total (23/month avg) |
| Average build time per proposal | 49.2 minutes (range: 31–68 min) |
| Copy-paste events per proposal (avg) | 14.3 clipboard transfers between Epic and Word |
| Word template files observed | 3 templates: personal, commercial, umbrella |
| Cover letters hand-typed | 100% — no saved cover letter content, no templates |
| Applied Epic proposal module | Never configured |
| Formatting time per proposal | 8–14 minutes (paste artifacts, table alignment) |
Every cover letter is written from scratch even though they’re 80% identical. The data shows 69 cover letters produced over the quarter. After removing client-specific details, they share the same structure: thank you, coverage summary, why this recommendation, call to action. An AI trained on these 69 examples produces indistinguishable cover letters in 3 seconds.
Set up Applied Epic proposal templates with merge fields (insured name, address, coverage options, premiums, deductibles, agent name). Build AI cover letter prompt trained on 69 captured letters — it knows the producers’ voice. Template generates branded PDF directly from Epic data.
Build 3 real proposals with the new system. Compare output quality to manual proposals. Adjust merge field mapping and cover letter tone. Producer Support should be producing proposals in under 8 minutes by end of week.
Every proposal takes 49 minutes of assembly. Producer Support can only build 3–4 per day with other duties. During busy season, proposals back up and producers wait. Every copy-paste is a transposition risk — wrong premium, wrong address, wrong coverage limit on a binding document.
Proposal build drops from 49 minutes to 6–8 minutes. Cover letters auto-generate in producer-specific voice. Zero copy-paste errors. Producer Support can handle 8–10 proposals/day during busy season.
Which model and why: Use Claude Opus or GPT-4o for cover letters. Tone matters here — these go to clients, so you want the model that writes most naturally. Sonnet and Flash produce competent but detectably-AI text. At 23 proposals/month averaging 150 output tokens each, monthly cost is approximately $0.35–$0.52 on Opus, essentially free on Sonnet. Use Opus.
You are the proposal writer for Lakeview Insurance Group, an independent
P&C agency in the suburbs of Chicago. Write professional, warm cover
letters for insurance proposals.
VOICE: Professional but approachable. Not stiff or corporate. These are
suburban families and local businesses who know us by name. Sound like a
trusted neighbor who happens to know insurance, not a corporation.
STRUCTURE:
1. Thank them for the opportunity (1 sentence)
2. Summarize what you reviewed — specific lines, not "your insurance"
3. Your recommendation and the specific dollar benefit
4. One coverage gap you noticed (if applicable)
5. Clear next step — call, meet, or reply
RULES:
- 4-5 sentences maximum. Nobody reads long cover letters.
- First name only. "Hi Sarah" not "Dear Mrs. Chen"
- Name the carrier: "By bundling with Travelers" not "by bundling"
- Name the dollar amount: "$847 per year" not "significant savings"
- If renewal: acknowledge how long they've been a client
- If new business: welcome them, don't oversell
- Never use: "I hope this finds you well," "don't hesitate to reach out,"
"please find attached," "in today's ever-changing landscape"
- Sign off as the producer by first name only
EXAMPLE INPUT:
"Commercial BOP renewal for Parkview Construction LLC. 6-year client.
Current with Hartford at $8,412. Requoted — Hartford renewal is $8,847
(+5.2%). Got Erie quote at $7,943. Recommend staying with Hartford because
their contractor endorsement is broader, net difference only $469 after
the endorsement value."
EXAMPLE OUTPUT:
"Dan — here's the renewal package for Parkview's BOP. Hartford came in at
$8,847, which is a 5.2% bump from last year. I did get Erie to $7,943, but
here's why I'm recommending you stay with Hartford: their contractor
liability endorsement covers completed operations claims that Erie excludes,
and on a construction account your size, that endorsement alone is worth
more than the $469 difference. I also want to talk about cyber liability
at renewal — you're processing client payment info on three job sites now
and your BOP doesn't cover a data breach. Call me when you've got 15
minutes and we'll button this up."
136 COIs per month, each manually generated and individually emailed. 67% are for the same recurring certificate holders. Applied Epic has batch certificate management — it was never configured.
The Commercial Lines CSRs generate 34 Certificates of Insurance per week on average (range: 22–48, peaking during construction season in March). Each COI requires: open Applied Epic → find policy → create certificate → enter certificate holder info → generate PDF → draft email → attach → send. Average: 11.4 minutes per COI.
| COIs generated (90 days) | 408 certificates |
| Average per week | 34 (range: 22–48) |
| Average generation time per COI | 11.4 minutes |
| Recurring certificate holders | 67% are repeat holders (general contractors, property managers) |
| Top 10 holders (by volume) | Account for 38% of all COI requests |
| Epic certificate batch mode | Installed, not configured |
| Client self-serve portal | Not enabled |
67% of COIs are for recurring certificate holders. The Commercial CSR re-types the same holder information every time — same general contractor address, same additional insured wording, same coverage verification. Saved templates would reduce these to a 2-click operation.
Commercial clients wait hours or overnight for COIs that could generate in seconds. During construction season (48 COIs/week), Commercial CSRs lose 9+ hours/week to certificate generation alone — leaving no time for quoting, endorsements, or new business. General contractors who need COIs at 6 AM Monday are stuck waiting until 8:30.
COI time drops from 11.4 min to 2 min for recurring holders, 4 min for new. Self-serve portal handles 30–40% of requests without CSR involvement. Commercial CSRs recover 12+ hours/month. Clients stop calling to ask “where’s my COI?”
Your Admin sends birthday cards and newsletters to every client the same way. She has no idea who’s up for renewal, who lapsed, or who hasn’t had a policy review in two years. The data exists in Applied Epic — Mailchimp can’t see it.
The Marketing/Admin Assistant manages Mailchimp campaigns, Canva social graphics, and birthday card mailing. In 90 days, she sent 6 newsletter campaigns and 187 birthday emails. Every message goes to the same undifferentiated list of 2,341 contacts.
| Mailchimp campaigns (90 days) | 6 newsletters, 187 birthday emails |
| Contact list size | 2,341 — one unsegmented list |
| Open rate / Click rate | 18.4% / 1.2% (industry avg for insurance: 21.3% / 2.1%) |
| Renewal-triggered emails | 0 — no renewal data in Mailchimp |
| Lapsed policy outreach | 0 — no lapse data in Mailchimp |
| Cross-sell campaigns | 0 — no coverage data in Mailchimp |
| Canva designs created (90 days) | 42 social media graphics |
| Canva sessions total time | 37.4 hours (avg 53 min per design) |
| Mailchimp session time | 18.7 hours — 14.2 on birthday cards alone |
This is not a marketing problem — it’s a data access problem. The Admin has no way to know which clients are up for renewal, which ones lapsed, or which ones only have one policy. Applied Epic has all of this data. Mailchimp can’t see it because nobody built the bridge.
Here’s the complete sync script. It reads a weekly Epic CSV export from Google Drive, updates Mailchimp contacts with insurance-specific merge fields, and creates auto-segments. Uses the Mailchimp Marketing API — no coding knowledge needed beyond pasting this script.
abc123def456-us21. The part after the dash (us21) is your server prefix.abc1234567./**
* Mailchimp Audience Sync from Applied Epic Export
* Runs weekly via Apps Script trigger
*
* Creates/updates these Mailchimp segments automatically:
* - Renewal 60 Days: policies expiring within 60 days
* - Lapsed 90 Days: cancelled/non-renewed in last 90 days
* - No Review 18+ Mo: no recorded activity in 18+ months
* - Monoline Auto: auto insurance only (cross-sell target for home)
* - Monoline Home: home insurance only (cross-sell target for auto)
* - New Client 90 Days: onboarded in last 90 days
* - High Value: total premium $5,000+
* - Commercial: any commercial lines
*
* Each segment gets its own automated email campaign in Mailchimp.
*/
const MC_CONFIG = {
apiKey: 'YOUR_MAILCHIMP_API_KEY', // e.g., 'abc123-us21'
serverPrefix: 'us21', // the part after the dash
listId: 'YOUR_LIST_ID', // 10-char audience ID
epicExportFolderId: 'YOUR_FOLDER_ID' // same Drive folder as commission script
};
function syncEpicToMailchimp() {
const clients = loadEpicClientExport_();
if (clients.length === 0) {
Logger.log('No client data found. Check Epic export folder.');
return;
}
const today = new Date();
let updated = 0, created = 0, errors = 0;
clients.forEach(client => {
if (!client.email || !client.email.includes('@')) return;
// Build merge fields for Mailchimp
const mergeFields = {
FNAME: client.firstName,
LNAME: client.lastName,
PHONE: client.phone,
LINES: client.linesOfBusiness,
PREMIUM: client.totalPremium.toString(),
EXPIRY: client.nextExpiry || '',
TENURE: client.tenureYears.toString(),
LASTACT: client.lastActivity || '',
STATUS: client.status
};
// Determine tags based on client data
const tags = [];
const daysToExpiry = client.nextExpiry
? Math.floor((new Date(client.nextExpiry) - today) / 86400000)
: 999;
const daysSinceActivity = client.lastActivity
? Math.floor((today - new Date(client.lastActivity)) / 86400000)
: 999;
if (daysToExpiry <= 60) tags.push('Renewal 60 Days');
if (client.status === 'lapsed') tags.push('Lapsed 90 Days');
if (daysSinceActivity >= 540) tags.push('No Review 18+ Mo');
if (client.lineCount === 1 && client.linesOfBusiness.includes('Auto'))
tags.push('Monoline Auto');
if (client.lineCount === 1 && client.linesOfBusiness.includes('Home'))
tags.push('Monoline Home');
if (client.tenureDays <= 90) tags.push('New Client 90 Days');
if (client.totalPremium >= 5000) tags.push('High Value');
if (['BOP','GL','WC','Commercial Auto'].some(l =>
client.linesOfBusiness.includes(l))) tags.push('Commercial');
// Upsert to Mailchimp
const subscriberHash = Utilities.computeDigest(
Utilities.DigestAlgorithm.MD5,
client.email.toLowerCase().trim()
).map(b => (b + 256) % 256).map(b =>
('0' + b.toString(16)).slice(-2)).join('');
const payload = {
email_address: client.email.toLowerCase().trim(),
status_if_new: 'subscribed',
merge_fields: mergeFields,
tags: tags
};
try {
mcApiCall_('PUT',
'/lists/' + MC_CONFIG.listId + '/members/' + subscriberHash,
payload);
updated++;
} catch (e) {
Logger.log('Error updating ' + client.email + ': ' + e.message);
errors++;
}
});
Logger.log('Sync complete: ' + updated + ' updated, ' + errors + ' errors');
}
function mcApiCall_(method, endpoint, payload) {
const url = 'https://' + MC_CONFIG.serverPrefix
+ '.api.mailchimp.com/3.0' + endpoint;
const options = {
method: method,
contentType: 'application/json',
headers: {
'Authorization': 'Basic ' + Utilities.base64Encode(
'anystring:' + MC_CONFIG.apiKey)
},
muteHttpExceptions: true
};
if (payload) options.payload = JSON.stringify(payload);
const response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode() >= 400) {
throw new Error('Mailchimp API error: ' + response.getContentText());
}
return JSON.parse(response.getContentText());
}
function loadEpicClientExport_() {
const folder = DriveApp.getFolderById(MC_CONFIG.epicExportFolderId);
const files = folder.getFilesByType(MimeType.CSV);
const clients = [];
// Get the most recent file
let latestFile = null;
let latestDate = new Date(0);
while (files.hasNext()) {
const f = files.next();
if (f.getDateCreated() > latestDate) {
latestDate = f.getDateCreated();
latestFile = f;
}
}
if (!latestFile) return clients;
const csv = Utilities.parseCsv(latestFile.getBlob().getDataAsString());
const today = new Date();
csv.slice(1).forEach(row => {
if (row.length < 8) return;
const effectiveDate = new Date(row[7] || today);
clients.push({
firstName: (row[0] || '').split(',')[1]?.trim() || row[0],
lastName: (row[0] || '').split(',')[0]?.trim() || '',
email: (row[1] || '').trim(),
phone: (row[2] || '').trim(),
linesOfBusiness: (row[3] || ''),
lineCount: (row[3] || '').split(',').length,
totalPremium: parseFloat(row[4]) || 0,
nextExpiry: row[5] || '',
lastActivity: row[6] || '',
status: (row[8] || 'active').toLowerCase(),
tenureYears: ((today - effectiveDate) / 31536000000).toFixed(1),
tenureDays: Math.floor((today - effectiveDate) / 86400000)
});
});
return clients;
}
Expected open rate improvement: Generic newsletters: 18.4%. Renewal-triggered emails: 28–34%. Monoline cross-sell: 24–29%. Lapsed outreach: 31–38% (people open these out of curiosity). The birthday cards are great — add a “your policy renews in [X] days” line when applicable and they become the highest-converting email in your stack.
Your book has $127,000–$194,000 in annual premium sitting in clients who already trust you. Nobody’s mining it because everyone’s too busy with the manual work above.
We analyzed the coverage data visible in Applied Epic sessions across the discovery period. Based on observed policy types, client counts, and industry benchmarks for independent P&C agencies, here’s what your book is leaving on the table:
Conservative estimate uses industry average close rates. Optimistic uses agency-specific rates (existing trust factor).
| Opportunity | Households | Avg Premium | Close Rate | Annual Revenue |
|---|---|---|---|---|
| Auto-only → add Home | 189 | $1,847 | 12–18% | $41,882 – $62,823 |
| Home-only → add Umbrella | 73 | $387 | 18–28% | $5,086 – $7,913 |
| Auto without Umbrella | 214 | $387 | 15–22% | $12,420 – $18,218 |
| Commercial without Cyber | 41 | $1,240 | 22–31% | $11,185 – $15,749 |
| Commercial without EPLI | 28 (5+ employees) | $2,100 | 15–22% | $8,820 – $12,936 |
| Personal lines without flood | 94 (flood zone) | $1,247 | 19–26% | $22,267 – $30,486 |
| Referral pipeline (satisfied clients) | ~480 est. | $2,847 avg | 3.2–4.8% | $25,681 – $46,155 |
| Total | $127,341 – $194,280 |
-- Cross-Sell Mining Query for Applied Epic Data Export
-- Run against your Epic client/policy export CSV
-- Identifies monoline clients with highest cross-sell potential
-- AUTO-ONLY HOUSEHOLDS (no home policy)
SELECT
c.client_id,
c.client_name,
c.phone,
c.email,
p.written_premium AS auto_premium,
p.effective_date,
DATEDIFF(CURDATE(), MAX(a.activity_date)) AS days_since_last_contact
FROM clients c
JOIN policies p ON c.client_id = p.client_id
AND p.line_of_business = 'Personal Auto'
AND p.status = 'Active'
LEFT JOIN policies ph ON c.client_id = ph.client_id
AND ph.line_of_business = 'Homeowners'
AND ph.status = 'Active'
LEFT JOIN activities a ON c.client_id = a.client_id
WHERE ph.policy_id IS NULL -- no active home policy
GROUP BY c.client_id
ORDER BY p.written_premium DESC;
-- COMMERCIAL WITHOUT CYBER LIABILITY
SELECT
c.client_id,
c.client_name,
c.phone,
c.email,
GROUP_CONCAT(DISTINCT p.line_of_business) AS current_lines,
SUM(p.written_premium) AS total_premium,
COUNT(DISTINCT p.policy_id) AS policy_count
FROM clients c
JOIN policies p ON c.client_id = p.client_id
AND p.status = 'Active'
AND p.line_of_business IN ('BOP', 'General Liability', 'Workers Comp', 'Commercial Auto')
LEFT JOIN policies pc ON c.client_id = pc.client_id
AND pc.line_of_business = 'Cyber Liability'
AND pc.status = 'Active'
WHERE pc.policy_id IS NULL
GROUP BY c.client_id
HAVING total_premium >= 3000 -- focus on accounts worth the effort
ORDER BY total_premium DESC;
-- PRIORITIZED OUTREACH LIST (weighted scoring)
SELECT
c.client_id,
c.client_name,
c.phone,
c.email,
COUNT(DISTINCT p.line_of_business) AS current_lines,
SUM(p.written_premium) AS total_premium,
DATEDIFF(CURDATE(), MIN(p.effective_date)) / 365.0 AS years_as_client,
-- Higher score = higher priority
(SUM(p.written_premium) / 1000)
+ (DATEDIFF(CURDATE(), MIN(p.effective_date)) / 365.0 * 2)
- (COUNT(DISTINCT p.line_of_business) * 5)
AS cross_sell_score
FROM clients c
JOIN policies p ON c.client_id = p.client_id
AND p.status = 'Active'
GROUP BY c.client_id
HAVING current_lines <= 2 -- monoline or two-line clients
ORDER BY cross_sell_score DESC
LIMIT 50;
Nobody is working this list because nobody has time to build it. The Personal Lines CSRs are buried in carrier portals. The Office Manager is maintaining a spreadsheet. The producers are waiting on proposals. Every finding above this one, when fixed, creates the capacity to work the cross-sell pipeline.
PHONE SCRIPT: AUTO-ONLY → ADD HOME
"Hi [NAME], this is [CSR] from Lakeview Insurance. I was
reviewing your account and noticed we have your auto coverage
but not your homeowners. A lot of our clients don't realize
that bundling auto and home saves $400-800 per year — and
you'd get a single point of contact for everything.
Would you be open to a quick home quote? I just need about
5 minutes and your property address. If the numbers don't
work, no pressure at all."
---
PHONE SCRIPT: NO UMBRELLA
"Hi [NAME], this is [CSR] from Lakeview. Quick call — I was
reviewing your account and wanted to mention umbrella
coverage. You've got [X] in assets between your home and
vehicles, and your current liability limits cap at [X].
An umbrella policy adds $1 million in protection for about
$200-300 per year. It's genuinely the best value in
insurance. Can I add a quote to your next renewal?"
---
PHONE SCRIPT: COMMERCIAL NO CYBER
"Hi [NAME], this is [CSR] from Lakeview. I wanted to flag
something on your business coverage — your BOP doesn't
include cyber liability, and with [REASON: employee PII /
client payment data / online presence], you've got real
exposure there. A standalone cyber policy runs about
$1,200/year and covers breach notification, legal defense,
and business interruption from a cyber event.
Can I send you a quote to look at alongside your renewal?"
---
EMAIL TEMPLATE: MONOLINE CROSS-SELL
Subject: Quick question about your coverage, [FNAME]
Hi [FNAME],
I was reviewing your account and noticed you have [CURRENT LINE]
with us but not [MISSING LINE]. Most of our clients who bundle
save $[ESTIMATED SAVINGS] per year.
Want me to run a quick [MISSING LINE] quote? Takes about 5
minutes on our end and there's zero obligation.
Just reply "yes" and I'll have numbers to you by end of day.
[AGENT NAME]
Lakeview Insurance Group
[PHONE]
Your team uses about a third of Applied Epic’s capabilities. The other two-thirds are being replaced by Google Sheets, manual processes, and human memory. This finding is the root cause of findings 1–6.
Applied Epic is the most used application across all 11 team members — 9,847 sessions in 90 days, averaging 38 sessions per person per day. But usage is almost entirely read and manual data entry. The automation, workflow, and integration features are dormant.
| Applied Epic sessions (team, 90 days) | 9,847 sessions total |
| Features actively used | Client lookup, policy view, activity notes, basic cert gen |
| Renewal workflows configured | 0 of 4 available workflow types |
| Automated activity triggers | 0 active triggers |
| Document management | ~30% of policies — rest in local folders or email |
| Commission reconciliation module | Read-only |
| Certificate management batch mode | Not configured |
| Client portal | Not enabled |
| Proposal generation | Not configured |
| Cross-sell / coverage gap reports | Never run |
| IVANS download connections | 2 of 5 carriers connected (partial) |
This is not a training problem. Your team knows how to use Epic for what they need. The features they’re missing were never configured by whoever set up the system. Your team adapted by building workarounds. Those workarounds now cost 100+ hours/month across the agency.
Print this checklist. Block 8 hours on a Tuesday. Work through it with your Epic admin login. Every item below is a built-in feature included in your existing Applied Epic license. Nothing here requires custom development, third-party tools, or Applied Systems professional services.
Total configuration time: 8 hours. Every feature listed above is built into Applied Epic and included in your existing license. It was never turned on. After this sprint, your team stops being the integration layer between systems that should be talking to each other.
214 clients haven’t had a policy review or meaningful contact in 24+ months. At your current non-renewal rate of 8.7%, that’s a retention leak you can see coming and prevent.
From Applied Epic activity records, we identified 214 client households with no recorded interaction in 24+ months. No policy review, no phone call, no email, no claim — nothing. These clients are paying their premiums on autopilot. They’re also the most likely to leave when a competitor offers a lower rate, because they have no relationship reinforcement.
| Clients with no contact in 24+ months | 214 households |
| Clients with no contact in 18–24 months | 147 additional households |
| Average premium per household | $2,847/year |
| Current non-renewal rate (agency-wide) | 8.7% |
| Non-renewal rate for no-contact clients | Estimated 14–18% (industry data for inactive accounts) |
| Total premium at elevated risk | 214 × $2,847 = $609,258/year |
Premium at elevated churn risk from 214 inactive client households
| Scenario | Clients | Churn Rate | Avg Premium | Annual Premium Lost |
|---|---|---|---|---|
| Without intervention (14–18% churn) | 214 | 16% avg | $2,847 | $97,445 |
| With proactive review (5.2–6.1% churn) | 214 | 5.6% avg | $2,847 | $34,142 |
| Premium saved by intervention | $63,303 | |||
| Plus: cross-sell during reviews (est.) | 214 | 8% conversion | $1,200 new | $20,544 |
| Total retention + cross-sell value | $83,847 – $134,235 |
This script generates a prioritized weekly outreach list and auto-drafts the emails. Set it up the same way as the commission script: Extensions → Apps Script → paste → run. Trigger weekly on Monday mornings.
/**
* Client Review Scheduler — Lakeview Insurance Group
*
* Reads Epic client export, identifies accounts with no activity
* in 18+ months, generates a prioritized outreach schedule,
* and creates Gmail draft emails ready to review and send.
*
* Priority scoring (higher = contact first):
* - Inactivity length: +1 point per month since last contact (max 36)
* - Premium value: +1 point per $500 in annual premium
* - Monoline risk: +10 points if client has only 1 policy line
* - Tenure bonus: +1 point per year as client (max 15)
*
* SETUP: Same as commission script
* 1. Open Google Sheets → Extensions → Apps Script
* 2. Paste this script
* 3. Update epicExportFolderId with your Drive folder ID
* 4. Run → Authorize
* 5. Trigger: weekly, Monday, 7 AM
*/
const REVIEW_CONFIG = {
epicExportFolderId: 'YOUR_FOLDER_ID',
inactivityThreshold: 540, // 18 months in days
outreachPerCSRPerWeek: 10,
csrEmails: {
'CSR 1': '[email protected]',
'CSR 2': '[email protected]',
'Comm CSR 1': '[email protected]',
'Comm CSR 2': '[email protected]'
},
agencyPhone: '(847) 555-0147'
};
function generateReviewSchedule() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName('Review Schedule');
if (!sheet) sheet = ss.insertSheet('Review Schedule');
sheet.clear();
// Headers
const headers = [
'Priority', 'Client Name', 'Phone', 'Email', 'Lines',
'Premium', 'Years as Client', 'Days Since Contact',
'Suggested Action', 'Talking Points', 'Assigned To',
'Status', 'Date Contacted', 'Notes'
];
sheet.appendRow(headers);
sheet.getRange(1, 1, 1, headers.length)
.setFontWeight('bold').setBackground('#f5f2ec').setFontSize(10);
sheet.setFrozenRows(1);
// Load and filter
const clients = loadClientExport_(ss);
const today = new Date();
const inactive = clients.filter(c => {
const daysSince = c.lastActivity
? Math.floor((today - new Date(c.lastActivity)) / 86400000)
: 999;
return daysSince >= REVIEW_CONFIG.inactivityThreshold;
});
// Score and sort
const scored = inactive.map(c => {
const daysSince = c.lastActivity
? Math.floor((today - new Date(c.lastActivity)) / 86400000)
: 999;
const tenureYears = c.originalEffective
? ((today - new Date(c.originalEffective)) / 31536000000).toFixed(1)
: 0;
let priority = 0;
priority += Math.min(daysSince / 30, 36);
priority += c.totalPremium / 500;
priority += c.lineCount === 1 ? 10 : 0;
priority += Math.min(parseFloat(tenureYears), 15);
priority = Math.round(priority * 10) / 10;
const action = daysSince > 730
? 'Phone call (2+ yrs inactive)'
: 'Email first, then call';
const points = [];
if (c.lineCount === 1) points.push('Monoline — discuss bundling');
if (c.totalPremium > 3000) points.push('High-value — umbrella review');
if (parseFloat(tenureYears) > 5) points.push(tenureYears + '-yr client — loyalty ack');
points.push('Coverage adequacy: limits may need updating');
return {
priority, name: c.name, phone: c.phone, email: c.email,
lines: c.linesOfBusiness, premium: c.totalPremium,
tenure: tenureYears, daysSince, action,
talkingPoints: points.join(' | '),
assignedTo: c.linesOfBusiness.includes('Commercial')
? 'Comm CSR 1' : 'CSR 1'
};
});
scored.sort((a, b) => b.priority - a.priority);
// Write to sheet
scored.forEach(c => {
sheet.appendRow([
c.priority, c.name, c.phone, c.email, c.lines,
c.premium, c.tenure, c.daysSince, c.action,
c.talkingPoints, c.assignedTo, 'Not Started', '', ''
]);
});
// Color-code by urgency
for (let i = 2; i <= Math.min(scored.length + 1, sheet.getLastRow()); i++) {
const days = sheet.getRange(i, 8).getValue();
if (days > 730) {
sheet.getRange(i, 1, 1, headers.length).setBackground('#fce4ec');
} else if (days > 540) {
sheet.getRange(i, 1, 1, headers.length).setBackground('#fff8e1');
}
}
// Auto-size
for (let i = 1; i <= headers.length; i++) sheet.autoResizeColumn(i);
// Create email drafts for top 20
const emailClients = scored.filter(c => c.action.includes('Email')).slice(0, 20);
emailClients.forEach(c => {
const subject = 'Quick coverage check-in, ' + c.name.split(',')[1]?.trim();
const body = generateReviewEmail_(c);
GmailApp.createDraft(c.email, subject, body);
});
Logger.log('Schedule generated: ' + scored.length + ' inactive clients, '
+ emailClients.length + ' email drafts created');
}
function generateReviewEmail_(client) {
const firstName = (client.name.split(',')[1] || client.name).trim();
return 'Hi ' + firstName + ',\n\n'
+ 'This is [YOUR NAME] from Lakeview Insurance. I was reviewing '
+ 'our client accounts and realized it\'s been a while since we '
+ 'last talked about your ' + client.lines + ' coverage.\n\n'
+ 'A lot can change — new vehicles, home improvements, life events '
+ '— and I want to make sure your coverage still fits. Would you be '
+ 'open to a quick 15-minute review call? No sales pitch, just '
+ 'making sure you\'re protected.\n\n'
+ 'Reply to this email or call me at ' + REVIEW_CONFIG.agencyPhone
+ ' — whatever\'s easier.\n\n'
+ 'Best,\n[YOUR NAME]\nLakeview Insurance Group';
}
function loadClientExport_(ss) {
const folder = DriveApp.getFolderById(REVIEW_CONFIG.epicExportFolderId);
const files = folder.getFilesByType(MimeType.CSV);
const clients = [];
let latestFile = null, latestDate = new Date(0);
while (files.hasNext()) {
const f = files.next();
if (f.getDateCreated() > latestDate) {
latestDate = f.getDateCreated();
latestFile = f;
}
}
if (!latestFile) return clients;
const csv = Utilities.parseCsv(latestFile.getBlob().getDataAsString());
csv.slice(1).forEach(row => {
if (row.length < 8) return;
clients.push({
name: row[0] || '', email: row[1] || '', phone: row[2] || '',
linesOfBusiness: row[3] || '', lineCount: (row[3] || '').split(',').length,
totalPremium: parseFloat(row[4]) || 0, nextExpiry: row[5] || '',
lastActivity: row[6] || '', originalEffective: row[7] || ''
});
});
return clients;
}
"Hi [FIRST NAME], this is [YOUR NAME] from Lakeview Insurance.
I'm calling because I was reviewing our client accounts and
realized we haven't connected in over two years. I want to
make sure your [LINES] coverage is still the right fit.
A few things I'd like to check:
- Have you added any vehicles or made home improvements?
- Are your liability limits still appropriate for your assets?
- [IF MONOLINE]: Have you considered bundling to save on premiums?
Do you have 10 minutes now, or should I call back at a better time?"
Your two producers are primarily out selling — that’s correct. But when they’re at their desks, 38% of that time goes to admin work that Producer Support should be handling.
The two producers logged 387 hours of desk time over 90 days (combined). That’s about 2.1 hours/day each — expected for producers who are primarily in the field. But the composition of that desk time is revealing:
| Total producer desk time (90 days, combined) | 387 hours |
| Epic: client lookup + pipeline review | 124 hours (productive — this is what producers should do) |
| Outlook: client correspondence | 68 hours (mixed — some productive, some admin) |
| Google Sheets: building prospect lists | 42 hours (admin — Producer Support should do this) |
| Adobe: reviewing/sending loss runs, apps | 37 hours (admin — Producer Support should do this) |
| Outlook: scheduling, appointment logistics | 26 hours (admin — Producer Support should do this) |
| Loss run requests sent manually (90 days) | 84 — each one a separate email composed from scratch |
| Admin work as % of desk time | 38% (Google Sheets + Acrobat + scheduling) |
38% of producer desk time is admin work — building prospect spreadsheets, pulling and formatting loss runs, scheduling appointments. This is exactly what Producer Support exists to do. The bottleneck: Producer Support currently spends 19 hours/month on proposal assembly (Finding #5). Fix proposal assembly, and Producer Support absorbs the producer admin work.
Step 1: Free up Producer Support time (depends on Finding #5). Once proposal assembly drops from 49 minutes to 8 minutes, Producer Support recovers 17 hours/month. That time gets redirected to absorbing the admin work producers are currently doing themselves.
Step 2: Establish the delegation handoff. Each producer sends a daily “request batch” email to Producer Support by 9 AM with everything they need: loss runs, prospect research, appointment scheduling. Producer Support batches and processes before noon. No more producers pulling their own loss runs one at a time in Acrobat.
Subject: Loss Run Request — [INSURED NAME] — [CARRIER]
To: [CARRIER LOSS RUN EMAIL]
[CARRIER]-specific header:
- Travelers: [email protected]
- Hartford: [email protected]
- Progressive: [email protected]
- Nationwide: [email protected]
- Erie: [email protected]
Dear Loss Run Department,
Please provide a 5-year loss run for the following account:
Named Insured: [INSURED NAME]
Policy Number: [POLICY NUMBER] (if known, otherwise "New Business")
Effective Date: [CURRENT EFF DATE or "New Business"]
Lines of Business: [AUTO / HOME / BOP / GL / WC / ALL]
Please send to: [YOUR AGENCY EMAIL]
Agency Name: Lakeview Insurance Group
Agency Code: [YOUR AGENCY CODE WITH THIS CARRIER]
Thank you,
[PRODUCER SUPPORT NAME]
Lakeview Insurance Group
[PHONE]
Step 3: Set up Epic pipeline dashboard for producers. In Applied Epic → Utilities → User Preferences → Home Screen Layout. For each producer, add the “Pipeline” widget showing: opportunities by stage (prospect / quoted / proposed / pending), total premium in pipeline, next actions due. Producers see their pipeline at a glance without building spreadsheets.
Move to Producer Support: Loss run requests (84/quarter), prospect list building (currently done in Sheets), appointment scheduling and logistics, proposal assembly (already automated in Finding #5), document prep and formatting.
Stays with Producer: Client relationships, sales meetings, coverage analysis, closing calls, referral development.
Producers recover 23 hours/month of desk time for pipeline work and client relationships. At your average new client premium of $3,200, redirecting even 10 hours/month to prospecting could yield 2–3 additional new accounts per month — $6,400–$9,600/month in new annual premium.
On an average Friday, 2.3 of your 11 staff are absent. Phone coverage drops 34%. The data doesn’t lie — Fridays are your weakest day.
| Average Friday attendance | 8.7 of 11 staff (79.1%) |
| Average Mon–Thu attendance | 10.4 of 11 staff (94.5%) |
| Friday activity volume vs Mon–Thu | 66% of weekday average |
| Lowest Friday (Feb 21) | 6 of 11 present (54.5%) |
| Friday missed calls (RingCentral, est.) | 3.4x higher than Mon–Thu average |
| Departments most affected | Customer Service (1–2 CSRs absent), Operations (Office Manager out 31% of Fridays) |
This isn’t a performance issue — it’s a structural one. Friday is when people take PTO, schedule appointments, or work half-days. The problem is that nobody adjusted coverage to account for the pattern. Clients don’t stop calling on Fridays.
Add one line to your PTO policy: “Friday PTO limited to 2 staff members per department. Submit Friday requests 2 weeks in advance.” Use a shared Google Sheet or your existing PTO system to manage Friday availability. Guarantee minimum 3 CSRs every Friday. Zero cost, zero technology, solves 80% of the problem.
Create a 4-week rotation: CSR 1 → CSR 2 → Comm CSR 1 → Comm CSR 2. The “Friday primary” person is guaranteed present and handles all inbound calls as first responder. Post the rotation in the break room and on a shared calendar. If the primary needs to swap, they find their own replacement. Simple, fair, transparent.
If you can’t solve it with scheduling, solve it with technology. Here’s the exact RingCentral configuration:
The data shows the gap. Pick the option that fits your culture. All three are ready to implement this week.
11 team members across 3 departments. Activity data by role — organized by function, not by name.
Working software delivered with this discovery. Paste-ready scripts, interactive tools, and configuration guides. Everything assumes zero technical knowledge.
Google Apps Script. Pulls carrier statements from Gmail, matches against Epic export, outputs exception report. Replaces 17 hrs/mo of manual matching.
Apps Script · 142 linesSQL queries for Applied Epic data export. Identifies auto-only, home-only, no-umbrella, no-cyber clients. Prioritized outreach list with scoring.
SQL · 3 queriesGoogle Apps Script. Identifies inactive clients, generates weekly outreach schedules, creates email drafts. Priority-scored by premium, tenure, and inactivity.
Apps Script · 98 linesSyncs Applied Epic client data to Mailchimp. Creates auto-segments: renewals, lapsed, inactive, monoline, new client, high-value, commercial.
Apps Script · 187 linesPrompt template trained on 69 captured cover letters. Paste into any AI assistant. Generates producer-voice proposal cover letters in seconds.
AI Prompt · System promptHTML tool. Reads Epic CSV export, displays renewal pipeline with 90/60/30-day views, CSR assignments, status tracking. Bridges the gap until Epic workflows are configured.
HTML Tool · InteractiveHTML tool. Upload a list of certificate requests, auto-populates recurring holder data, generates batch COI package for Epic import. Turns 8 individual COIs into 1 batch operation.
HTML Tool · Interactive4 Outlook email templates with merge fields: adjuster assigned, inspection scheduled, payment issued, claim closed. Pre-written professional language, personalized per client.
Email Templates · 4 templatesStep-by-step guide for the 8-hour Epic sprint. Every toggle, every setting, every workflow rule. Printable checklist format. Covers all 8 modules to activate.
Config Guide · 8 modulesEmail template with merge fields for carrier-specific loss run requests. Standardizes the format producers use, makes it batch-able by Producer Support.
Email Template · 5 carriersDon’t know how to set any of this up? Copy the entire tools section and paste it into ChatGPT, Claude, or Gemini. Say “help me set up the commission reconciliation script step by step.” It will walk you through every click.
Paste a list of COI requests (one per line: policy number, certificate holder name). The tool pre-fills recurring holder data and generates a batch-ready import file for Applied Epic.
Interactive view of your renewal pipeline. In a real deployment, this reads from an Applied Epic CSV export. This demo is pre-loaded with sample data matching Lakeview’s profile.
| Policy # | Insured | Line | Expiry | Premium | CSR | Status |
|---|---|---|---|---|---|---|
| PA-2026-04817 | Chen, Sarah & David | Auto + Home | Apr 2 | $4,218 | CSR 1 | Quoted |
| HO-2026-02341 | Martinez, Roberto | Homeowners | Apr 5 | $2,847 | CSR 2 | Bound |
| BOP-2026-01293 | Lakeshore Dental Group | BOP + WC | Apr 8 | $8,412 | Comm CSR 1 | No Contact |
| PA-2026-03412 | Thompson, Angela | Auto | Apr 10 | $1,634 | CSR 1 | Letter Sent |
| GL-2026-00847 | Parkview Construction LLC | GL + Comm Auto | Apr 12 | $12,341 | Comm CSR 2 | Quoted |
| HO-2026-05218 | Williams, Terrence & Joyce | Home + Umbrella | Apr 15 | $3,187 | CSR 2 | Letter Sent |
| WC-2026-00394 | Great Lakes Landscaping | Workers Comp | Apr 18 | $6,847 | Comm CSR 1 | Letter Sent |
Showing 7 of 23 upcoming 30-day renewals. In production, this reads from your Epic CSV export and updates daily. Red = no contact made. Amber = in process. Green = bound/renewed.
47 policies expiring in 31–60 days
Total premium: $142,847. 60-day letters sent for 31 of 47.
In production, this panel displays the full sortable table with CSR assignments and status tracking.
63 policies expiring in 61–90 days
Total premium: $187,341. 90-day letters queued for all 63.
In production, this panel shows the 90-day pipeline with carrier and line breakdown charts.
217 policies in the renewal pipeline
Total annual premium: $618,247. Avg premium per policy: $2,849.
Select a coverage gap type to see the opportunities in your book. In production, this reads from Applied Epic data. Demo pre-loaded with Lakeview’s profile.
| Client | Auto Premium | Years w/ Agency | Est. Home Premium | Priority Score | Talk Track |
|---|---|---|---|---|---|
| Novak, James & Patricia | $3,412 | 8.3 | $2,240 | 94 | Bundle save est. $480/yr. Renewal in 47 days. |
| Okafor, Chidera | $2,847 | 5.1 | $1,987 | 87 | Multi-car discount. New home purchased 6mo ago. |
| Kowalski, Michael | $2,634 | 12.7 | $1,847 | 78 | Long-term loyalty. Annual review overdue 2 yrs. |
| Ramirez, Luis & Elena | $2,189 | 3.4 | $2,412 | 71 | Young family, growing assets. Umbrella conversation. |
Showing top 4 of 189 auto-only households. Priority score weights: premium size (30%), tenure (25%), recency of contact (25%), coverage gap value (20%).
The time savings are significant. The revenue opportunity is transformational. Here’s the business case.
Combines cross-sell revenue, retention savings, capacity gains, and efficiency dividends.
| Revenue Stream | Basis | Conservative | Optimistic |
|---|---|---|---|
| Cross-sell: Auto-only → Home | 189 households × $1,847 × 12–18% | $41,882 | $62,823 |
| Cross-sell: Umbrella gap | 287 households × $387 × 15–25% | $16,660 | $27,766 |
| Cross-sell: Cyber liability | 41 businesses × $1,240 × 22–31% | $11,185 | $15,749 |
| Cross-sell: EPLI | 28 businesses × $2,100 × 15–22% | $8,820 | $12,936 |
| Cross-sell: Flood (zone clients) | 94 households × $1,247 × 19–26% | $22,267 | $30,486 |
| Retention: Proactive review saves | 214 inactive × reduced churn × $2,847 | $63,303 | $97,445 |
| Referral pipeline (new) | ~480 satisfied × $2,847 × 3.2–4.8% | $25,681 | $46,155 |
| Capacity gain: additional quotes | ~1,100 extra quotes/yr × 24% close × $2,847 | $24,202 | $34,640 |
| Total Annual Revenue Opportunity | $214,000 | $328,000 |
AI compute for proposal cover letters ($6), claims status parsing ($4), marketing segmentation ($4), cross-sell prioritization ($4), retention scoring ($5). Everything else is configuration of tools you already own.
Equivalent to 1.5–1.9 FTEs. You don’t need to hire anyone. You need to turn on the software you already own and build the bridges between systems that should be talking to each other.
The real ROI isn’t the 387–491 hours saved. It’s where those hours go. Every hour your Personal Lines CSR spends re-keying data into carrier portals is an hour she’s not calling the auto-only client to talk about bundling. Every hour your Office Manager spends on the renewal spreadsheet is an hour she’s not training the junior CSR. Every hour your Claims Coordinator spends logging into portals is an hour a client is waiting for an update.
The automation creates the capacity. The revenue comes from how you deploy that capacity.
What a custom AI assistant connected to Applied Epic would look like. Applied Systems’ API access is required. Here’s the architecture for when that becomes available.
Applied Systems is building its own AI layer (Applied AI), but it’s not broadly available yet. In the meantime, here’s what a custom AI assistant connected to your Epic data would do — and what it would replace.
Applied Epic AI Assistant Architecture
--------------------------------------
[User Query]
|
v
[AI Assistant (Claude/GPT)]
|
v
[Applied Epic MCP Server]
|--- read_client(name) → client record, policies, activities
|--- search_policies(filters) → matching policies
|--- get_renewals(date_range) → upcoming renewals with CSR assignments
|--- generate_certificate(policy_id, holder_id) → COI PDF
|--- get_claim_status(claim_number) → current status, timeline
|--- run_cross_sell_report(filters) → monoline clients, coverage gaps
|--- create_proposal(client_id, options) → branded PDF
|--- create_activity(client_id, type, notes) → activity note in Epic
|
v
[Applied Epic REST API / IVANS]
|--- Client Management endpoints
|--- Policy Management endpoints
|--- Certificate Management endpoints
|--- Claims endpoints
|--- Activity/Workflow endpoints
|--- Commission endpoints
|--- Reporting endpoints
Current API status:
- Applied Epic SDK: Available to Applied partners (requires partnership agreement)
- IVANS connectivity: Available now for download/upload
- REST API: Limited availability, expanding in 2026
Model recommendations by task (with monthly cost at Lakeview's volume):
- Proposal cover letters: Claude Opus ($0.52/mo @ 23 proposals)
→ Tone matters. Opus writes the most natural insurance language.
- Claims status parsing: Gemini Flash ($0.48/mo @ 14 checks/day)
→ Speed matters, complexity is low. Flash at $0.075/1M tokens.
- Cross-sell prioritization: Claude Sonnet ($0.85/mo @ 189 accounts)
→ Reasoning + speed balance. Sonnet at $3/1M input tokens.
- Marketing segmentation: Gemini Flash ($0.32/mo @ 2,341 contacts)
→ Batch classification task. Flash is the right price point.
- Retention scoring: Claude Sonnet ($0.67/mo @ 214 accounts)
→ Nuanced priority scoring. Sonnet handles the logic well.
- Total AI compute: $2.84/mo for current volume
(The $175-280/mo estimate in the exec summary includes headroom
for scaling to full Applied Epic API integration when available)
- Applied AI: In development, early access program
Recommended path:
1. Implement IVANS-based automations NOW (claims, commissions, downloads)
2. Build Google Apps Script bridges for data that can be exported as CSV
3. Apply for Applied Epic API access when broadly available
4. Build full AI assistant when API access is granted
Activity patterns analyzed locally via Go2 desktop app. No data stored externally. Powered by Cowork.ai telemetry capture.
Pick the finding that bothers you most, follow the steps, and see what changes. If you want help implementing any of it, reply to this email.