Get Started with Aeion Legal

Stand up a law firm in five steps — firm settings, billing rates, matters with conflict check, court deadlines, trust accounting, and contract lifecycle management. Auto-CRUD on every collection plus a dedicated CLM router for obligation tracking, renewals, versioning, and portfolio analytics.

1

Configure Firm Settings

legal_settings is a singleton — one row per tenant — that drives default rates, jurisdictions, holiday set, trust protections, and e-signature provider. Create or update it through auto-CRUD:

```bash POST /api/v1/legal_settings { "firmName": "Sterling Law Group", "jurisdictions": ["CA", "NY", "TX"], "defaultHourlyRate": 350, "billingIncrement": 6, "matterNumberFormat": "YYYY-####", "clientNumberFormat": "CLT-#####",

"trustAccountEnabled": true, "trustOverdraftProtection": true, "replenishmentAlertThreshold": 500,

"defaultHolidaySet": "federal", "deadlineWarningDays": 90, "courtDayCalculation": true, "autoCreateDockets": true,

"eSignatureProvider": "native" } ```

> The settings collection is enforced as a singleton — subsequent POSTs return the existing row rather than creating duplicates. Use PATCH /api/v1/legal_settings/<id> to update.

2

Set Billing Rates

PriorityRate typeWhen it wins
1Matter-specificOne-off premium engagement
2Client-specificMaster service agreement at company level
3Practice-areaHigher rate for litigation vs corporate
4Attorney-defaultFallback for everything else
3

Open a Matter (with Conflict Check)

Matters are the core entity. Before creating one, sweep the conflict database for parties already on file.

Record a conflict candidate:

bash POST /api/v1/legal_conflicts { "name": "Johnson & Johnson", "type": "company", "matter": "<existingMatterId>", "side": "opposing" }

Each conflict row stores the normalized name (lowercased, punctuation-stripped, alphabetically sorted words) so fuzzy lookups stay deterministic. To screen a new matter, filter the collection with a string contains operator against your normalized prospect name:

bash GET /api/v1/legal_conflicts?where[name][contains]=johnson

Decide based on the result count (any exact-name hit blocks; partial hits require attorney sign-off). For a programmatic check, query the legal_conflicts endpoint directly from your own integration.

Open the matter:

bash POST /api/v1/legal_matters { "title": "Doe v. Acme Corp", "matterNumber": "2026-0001", "practiceArea": "litigation", "clientContact": "<contactId>", "clientCompany": "<companyId>", "status": "open", "openedAt": "2026-05-20" }

Add opposing parties in legal_matter_parties:

bash POST /api/v1/legal_matter_parties { "matter": "<matterId>", "name": "Acme Corp", "type": "company", "side": "opposing", "role": "defendant" }

Log time against the matter (rate resolved from Step 2's hierarchy):

bash POST /api/v1/legal_time_entries { "matter": "<matterId>", "attorney": "<attorneyId>", "date": "2026-05-20", "hours": 2.5, "description": "Draft motion to compel discovery response", "activityCode": "drafting", "billable": true }

4

Calendar Court Deadlines

Aeion stores jurisdiction-specific deadline rules in legal_court_rules and statutes of limitation in legal_sol_rules. Both ship with seed data for federal courts plus CA / NY / TX / FL. Dockets — the actionable deadline records — live in legal_dockets.

Inspect available court rules:

bash GET /api/v1/legal_court_rules?where[jurisdiction][equals]=CA

Look up a statute of limitations:

bash GET /api/v1/legal_sol_rules?where[jurisdiction][equals]=CA&where[claimType][equals]=personal_injury

Each rule includes the citation, the limitation period, and the discovery-rule applicability so you can show the source in the UI.

Create a deadline docket:

bash POST /api/v1/legal_dockets { "matter": "<matterId>", "title": "Motion to Compel Discovery Response", "deadlineDate": "2026-06-18", "calculationType": "court_day", "basisDays": 30, "basisDate": "2026-05-15", "warningDays": 7, "jurisdiction": "CA", "assignedTo": "<attorneyId>", "priority": "high" }

Query upcoming deadlines for a matter (next 30 days):

bash GET /api/v1/legal_dockets?where[matter][equals]=<matterId>&where[deadlineDate][before]=2026-06-19&sort=deadlineDate

The dashboard widget pulls the same query and groups by status (upcoming / due / overdue).

5

Trust Accounting + Contract Lifecycle

IOLTA trust ledger. Every deposit and withdrawal is a row in legal_trust_ledger linked to a matter. Balances are computed from the ledger — no separate stored balance to drift.

```bash # Initial retainer deposit POST /api/v1/legal_trust_ledger { "matter": "<matterId>", "transactionType": "deposit", "amount": 5000, "description": "Advanced retainer deposit", "referenceNumber": "CHK-12345", "authorizedBy": "<attorneyId>", "transactionDate": "2026-05-20" }

# Withdrawal to pay an invoice POST /api/v1/legal_trust_ledger { "matter": "<matterId>", "transactionType": "withdrawal", "amount": 1000, "description": "Invoice #123 paid from trust", "authorizedBy": "<attorneyId>" } ```

Withdrawals are guarded automatically: requesting more than the matter's current balance is rejected with an error that includes the available balance and the requested amount, so your UI (or your own integration) can show exactly why it was blocked. Corrections (transactionType: "correction") require an authorizing user and bypass the guard for legitimate ledger fixes.

Compute matter balance by aggregating the ledger:

bash GET /api/v1/legal_trust_ledger?where[matter][equals]=<matterId>&sort=-transactionDate

Sum deposits minus withdrawals client-side, or pull the same computed balance through the trust ledger endpoint for your own reporting.

Contract Lifecycle Management. Beyond auto-CRUD on legal_contracts, contract_versions, contract_obligations, and contract_compliance_tags, Aeion ships a dedicated CLM router at /api/legal/clm/* for obligation tracking, renewal scheduling, version control, and portfolio analytics:

```bash # Auto-extract obligations from a signed contract POST /api/legal/clm/obligations/<contractId>/extract

# Mark an obligation complete PATCH /api/legal/clm/obligations/<obligationId>/complete

# Mark an obligation in breach PATCH /api/legal/clm/obligations/<obligationId>/breach

# Upcoming renewals (next 90 days) GET /api/legal/clm/renewals/upcoming

# Save a new version with diff capture POST /api/legal/clm/versions/<contractId>

# Compare two versions side-by-side POST /api/legal/clm/versions/compare { "fromVersionId": "...", "toVersionId": "..." }

# Portfolio-wide analytics GET /api/legal/clm/analytics/portfolio GET /api/legal/clm/analytics/obligations GET /api/legal/clm/analytics/vendors GET /api/legal/clm/analytics/compliance GET /api/legal/clm/analytics/timeline/<contractId> ```

A daily check at 08:00 sweeps contracts at risk of lapsing and sends reminders — or auto-renews them — based on each contract's configured renewal policy.

Quick Reference

SlugPurpose
`legal_matters`The matter itself
`legal_matter_parties`Plaintiffs, defendants, third parties
`legal_conflicts`Conflict database for screening
`legal_billing_rates`4-tier rate hierarchy
`legal_time_entries`Billable time with auto-resolved rate
`legal_expenses`Reimbursable costs
`legal_invoices`Generated invoices for client review
`legal_retainers`Retainer agreements + balances
`legal_trust_ledger`IOLTA deposits / withdrawals
`legal_tasks`Per-matter todos
`legal_notes`Case notes
`legal_communications`Logged client/court communications
`legal_dockets`Calendared deadlines
`legal_court_rules`Per-jurisdiction deadline rules (seed data)
`legal_sol_rules`Statute of limitations rules (seed data)
`legal_matter_templates`Reusable matter shells
`legal_settlements`Settlement agreements
`legal_precedents`Saved precedents / research

FAQ

Matters in `legal_matters`, opposing parties in `legal_matter_parties`, and your clients in the platform-wide `crm_contacts` / `crm_companies` collections from the CRM module. The matter row holds `clientContact` and `clientCompany` foreign keys into CRM, so customer data is shared rather than duplicated.

When a time entry is created, Aeion looks up the active rates for that attorney and walks the priority chain (matter → client → practice area → attorney default), applying the first match. Expired rates are filtered out automatically. If nothing matches, it falls back to your firm's configured default hourly rate.

Balances are derived — never stored — by summing deposits minus withdrawals for a given matter, recalculated fresh on every request so it can never drift out of sync. A withdrawal exceeding the balance is rejected with an error carrying the available balance and the requested amount; the client renders that as a hard stop with an option to deposit more or reduce the amount.

Federal plus California, New York, Texas, and Florida ship as seed data in `legal_court_rules` and `legal_sol_rules`, including state-specific holidays (e.g. César Chávez Day for CA, Lincoln's Birthday for NY). Adding a new jurisdiction is a row insert plus a holiday set — no code change.

Yes. `calculationType: "court_day"` skips weekends + holidays; `"business_day"` skips weekends; `"calendar_day"` counts everything. If the computed date lands on a weekend or holiday, the engine advances to the next valid court day per the jurisdiction's rules.

The CLM service flags it via `GET /api/legal/clm/obligations/overdue` and the dashboard widget shows it under "Action required." Mark complete with `PATCH .../complete`; mark breached with `PATCH .../breach`, which records breach metadata and emits `legal.contract.obligation_breached` so other modules (notifications, finance) can react.

A daily cron at 08:00 walks `legal_contracts` whose `renewalDate` falls inside the warning window (default 90 days) and either auto-renews (when `autoRenew: true`) or files a reminder docket against the matter. Inspect upcoming work at `GET /api/legal/clm/renewals/upcoming` and expiring contracts at `GET /api/legal/clm/renewals/expiring`.

Yes — `POST /api/legal/clm/versions/compare` with `fromVersionId` and `toVersionId` returns a structured diff. `POST /api/legal/clm/versions/<contractId>` saves a new version when the contract body changes, and `POST /api/legal/clm/versions/<versionId>/restore` rolls back. Versions are immutable and audit-stamped.

Yes. The native provider issues signed-URL envelopes from the platform's client portal. DocuSign and HelloSign / Dropbox Sign are also supported — drop your credentials into Settings, switch your preferred provider, and Aeion routes envelope creation through the chosen vendor. If no provider is configured, the API returns a clear `503` error instead of pretending a document was sent.

Names are normalized (lowercased, punctuation stripped, words sorted alphabetically) before they're stored in `legal_conflicts`. A new-matter screen runs `where[name][contains]` against the normalized form. Exact matches block matter creation outright; near-matches surface in the UI for attorney sign-off.

`legal.matter.opened`, `legal.matter.closed`, `legal.time_entry.created`, `legal.trust.deposited`, `legal.trust.withdrawn`, `legal.trust.overdraft_blocked`, `legal.docket.scheduled`, `legal.docket.due_soon`, `legal.contract.obligation_extracted`, `legal.contract.obligation_breached`, `legal.contract.renewal_due`, `legal.contract.renewed`. Subscribe with `api.events.subscribe(...)` from any other module.

Yes — `POST /api/legal/knowledge/query` accepts a question, optional jurisdiction, and optional practice area. The handler routes through the platform AI service; if your provider isn't configured the response includes a `status: "pending"` flag so you can render a clear "not configured" state instead of a confident-but-wrong answer.

Open the Legal Dashboard