Systems Library / Industry Applications / How to Automate Law Firm Client Intake
Industry Applications legal

How to Automate Law Firm Client Intake

Streamline client intake with automated forms, screening, and onboarding.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Automating law firm client intake turns the messiest part of starting a new engagement into a smooth pipeline. I built this for a firm where intake meant phone tag, misplaced forms, and a week before the attorney had everything needed to start work. Now clients fill out a smart form, AI qualifies the case, and the attorney gets a complete intake package before the first call.

What You Need Before Starting

Step 1: Build the Intake Database

import sqlite3
from datetime import datetime

def init_intake_db(db_path="legal_intake.db"):
    conn = sqlite3.connect(db_path)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS intake_submissions (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            full_name TEXT,
            email TEXT,
            phone TEXT,
            case_type TEXT,
            description TEXT,
            urgency TEXT,
            ai_qualification TEXT,
            ai_score INTEGER,
            status TEXT DEFAULT 'pending',
            assigned_attorney TEXT,
            submitted_at TEXT,
            reviewed_at TEXT
        )
    """)
    conn.commit()
    conn.close()

Step 2: Build the Qualification Engine

import anthropic
from dotenv import load_dotenv
load_dotenv()

PRACTICE_AREAS = {
    "personal_injury": {"min_value": 25000, "statute_check": True},
    "business_litigation": {"min_value": 50000, "statute_check": True},
    "family_law": {"min_value": 0, "statute_check": False},
    "estate_planning": {"min_value": 0, "statute_check": False},
    "employment": {"min_value": 10000, "statute_check": True},
}

def qualify_intake(submission):
    client = anthropic.Anthropic()
    
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1024,
        system="""You are a legal intake specialist. Analyze the potential client's case and provide:
1. Case type classification
2. Preliminary merit assessment (strong/moderate/weak/insufficient info)
3. Estimated case value range if applicable
4. Statute of limitations concerns
5. Conflict check flags (names of opposing parties mentioned)
6. Key questions the attorney should ask in the first consultation
7. Qualification score 1-10

Return as structured text. Be objective. Flag insufficient information rather than guessing.""",
        messages=[{
            "role": "user",
            "content": f"""New intake submission:
Name: {submission['full_name']}
Case Type: {submission['case_type']}
Urgency: {submission['urgency']}
Description: {submission['description']}"""
        }]
    )
    
    return response.content[0].text

Step 3: Process Incoming Submissions

def process_intake(submission, db_path="legal_intake.db"):
    qualification = qualify_intake(submission)
    
    score = extract_score(qualification)
    
    conn = sqlite3.connect(db_path)
    conn.execute("""
        INSERT INTO intake_submissions (full_name, email, phone, case_type, description,
            urgency, ai_qualification, ai_score, submitted_at)
        VALUES (?,?,?,?,?,?,?,?,?)
    """, (submission["full_name"], submission["email"], submission["phone"],
          submission["case_type"], submission["description"], submission["urgency"],
          qualification, score, datetime.utcnow().isoformat()))
    conn.commit()
    conn.close()
    
    if submission["urgency"] == "emergency" or score >= 8:
        notify_attorney(submission, qualification, priority="high")
    
    send_confirmation_email(submission["email"], submission["full_name"])
    
    return {"qualification": qualification, "score": score}

def extract_score(qualification_text):
    import re
    match = re.search(r"(?:score|rating)[:\s]*(\d+)", qualification_text.lower())
    return int(match.group(1)) if match else 5

Step 4: Build the Intake API

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class IntakeForm(BaseModel):
    full_name: str
    email: str
    phone: str
    case_type: str
    description: str
    urgency: str = "normal"

@app.post("/intake/submit")
def submit_intake(form: IntakeForm):
    result = process_intake(form.dict())
    return {
        "status": "received",
        "message": f"Thank you {form.full_name}. We will review your case and contact you within 24 hours."
    }

@app.get("/intake/pending")
def get_pending():
    conn = sqlite3.connect("legal_intake.db")
    rows = conn.execute("""
        SELECT id, full_name, case_type, urgency, ai_score, submitted_at
        FROM intake_submissions WHERE status = 'pending'
        ORDER BY ai_score DESC, submitted_at ASC
    """).fetchall()
    conn.close()
    return [{"id": r[0], "name": r[1], "type": r[2], "urgency": r[3], "score": r[4], "submitted": r[5]} for r in rows]

Step 5: Attorney Review Dashboard

@app.get("/intake/{intake_id}")
def get_intake_detail(intake_id: int):
    conn = sqlite3.connect("legal_intake.db")
    row = conn.execute("SELECT * FROM intake_submissions WHERE id = ?", (intake_id,)).fetchone()
    conn.close()
    
    if not row:
        return {"error": "Not found"}
    
    columns = ["id", "full_name", "email", "phone", "case_type", "description",
               "urgency", "ai_qualification", "ai_score", "status", "assigned_attorney",
               "submitted_at", "reviewed_at"]
    return dict(zip(columns, row))

@app.post("/intake/{intake_id}/assign")
def assign_attorney(intake_id: int, attorney: str):
    conn = sqlite3.connect("legal_intake.db")
    conn.execute(
        "UPDATE intake_submissions SET assigned_attorney = ?, status = 'assigned', reviewed_at = ? WHERE id = ?",
        (attorney, datetime.utcnow().isoformat(), intake_id)
    )
    conn.commit()
    conn.close()
    return {"status": "assigned", "attorney": attorney}

What to Build Next

Add conflict checking. Before qualifying a case, search your existing client database for the opposing party's name. Flag potential conflicts immediately so attorneys know before the consultation.

Related Reading

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

Related Systems