How to Automate Client Retainer Billing and Tracking
Track retainer usage and generate billing statements automatically.
Jay Banlasan
The AI Systems Guy
Retainer clients pay a fixed amount but usage varies. I built a system to automate retainer billing and track usage so both you and the client know exactly where hours stand. Monthly statements, overage alerts, and rollover calculations all happen automatically.
Transparency builds trust. This system provides it.
What You Need Before Starting
- Python 3.8+
- Time tracking data source
- Retainer contract terms
- Client notification system
Step 1: Define Retainer Contracts
RETAINER_CONTRACTS = {
"acme-001": {
"client": "Acme Corp",
"monthly_hours": 40,
"hourly_rate": 150,
"monthly_fee": 5000,
"overage_rate": 175,
"rollover_hours": True,
"max_rollover": 10
}
}
Step 2: Track Usage Against Retainer
import sqlite3
from datetime import datetime
def init_retainer_db(db_path="retainers.db"):
conn = sqlite3.connect(db_path)
conn.execute("""
CREATE TABLE IF NOT EXISTS retainer_usage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
client_id TEXT,
month TEXT,
hours_used REAL DEFAULT 0,
hours_allocated REAL,
rollover_hours REAL DEFAULT 0,
overage_hours REAL DEFAULT 0,
overage_amount REAL DEFAULT 0
)
""")
conn.commit()
return conn
def log_hours(conn, client_id, hours, description):
month = datetime.now().strftime("%Y-%m")
conn.execute(
"UPDATE retainer_usage SET hours_used = hours_used + ? WHERE client_id=? AND month=?",
(hours, client_id, month)
)
conn.commit()
Step 3: Calculate Monthly Retainer Status
def calculate_retainer_status(conn, client_id, month):
contract = RETAINER_CONTRACTS[client_id]
usage = conn.execute(
"SELECT hours_used, hours_allocated, rollover_hours FROM retainer_usage WHERE client_id=? AND month=?",
(client_id, month)
).fetchone()
if not usage:
return None
hours_used, allocated, rollover = usage
total_available = allocated + rollover
remaining = total_available - hours_used
overage = max(0, hours_used - total_available)
overage_cost = overage * contract["overage_rate"]
return {
"client": contract["client"],
"hours_allocated": allocated,
"rollover_from_last": rollover,
"total_available": total_available,
"hours_used": hours_used,
"remaining": max(0, remaining),
"overage_hours": overage,
"overage_cost": overage_cost,
"utilization": round(hours_used / total_available * 100, 1) if total_available else 0
}
Step 4: Generate Monthly Statement
def generate_retainer_statement(status, month):
statement = f"# Retainer Statement: {status['client']}\n"
statement += f"## {month}\n\n"
statement += f"| Metric | Value |\n|---|---|\n"
statement += f"| Hours Allocated | {status['hours_allocated']} |\n"
statement += f"| Rollover Hours | {status['rollover_from_last']} |\n"
statement += f"| Total Available | {status['total_available']} |\n"
statement += f"| Hours Used | {status['hours_used']} |\n"
statement += f"| Remaining | {status['remaining']} |\n"
statement += f"| Utilization | {status['utilization']}% |\n"
if status["overage_hours"] > 0:
statement += f"\n**Overage: {status['overage_hours']} hours at ${RETAINER_CONTRACTS.get('acme-001', {}).get('overage_rate', 0)}/hr = ${status['overage_cost']:.2f}**\n"
return statement
Step 5: Alert on Threshold
def check_retainer_alerts(conn):
month = datetime.now().strftime("%Y-%m")
alerts = []
for client_id, contract in RETAINER_CONTRACTS.items():
status = calculate_retainer_status(conn, client_id, month)
if not status:
continue
if status["utilization"] >= 90:
alerts.append({"client": contract["client"], "type": "near_limit",
"message": f"{status['utilization']}% utilized. {status['remaining']} hours remaining."})
elif status["overage_hours"] > 0:
alerts.append({"client": contract["client"], "type": "overage",
"message": f"Overage: {status['overage_hours']}h (${status['overage_cost']:.2f})"})
return alerts
What to Build Next
Add automatic scope recommendations when clients consistently use more or less than their allocation. Upsell clients who always go over. Downgrade clients who consistently underuse. Data-driven account management.
Related Reading
- Building Your First Automation: A Complete Guide - automation fundamentals
- How Systems Compound Over Time - retainer data compounds insight
- AI-Powered Reporting That Actually Gets Read - client-facing reports that work
Want this system built for your business?
Get a free assessment. We will map every system your business needs and show you the ROI.
Get Your Free Assessment