Agora (Legal)
Enterprise legal tech for law firms — matter management, trust accounting, AI-assisted document review, and time-tracking billing.
URL: agora.redbroomsoftware.comStatus: LIVE Tier: T2 (narrow surface)
What you can integrate
- Matter management — list, create, update cases
- Document management — AI-assisted upload, retrieval, review
- Time tracking — "Ghost Timer" automatic time capture + manual entries
- Billing & trust — invoice generation and IOLTA trust accounting
- AI services — multi-provider document review and legal research
Authentication
http
Authorization: Bearer <api_key>
Content-Type: application/jsonUser identity flows through Camino SSO (OAuth2 + PKCE). Server-to-server partners use per-partner API keys issued from the Agora admin console.
Endpoints
| Method | Path |
|---|---|
| GET, POST | /api/ai |
| GET, POST | /api/ai/case-analysis |
| POST | /api/ai/chat |
| POST | /api/ai/deadlines |
| GET, POST | /api/ai/document-summary |
| POST | /api/ai/draft-document |
| POST | /api/ai/research |
| GET, PATCH | /api/ai/reviews/:id |
| GET, POST | /api/appointments |
| GET, PATCH, DELETE | /api/appointments/:id |
59 total — 3 admin/cron/internal (hidden) — +46 more primary endpoints not shown. Source: src/routes/api/**/+server.{ts,js} in the agora repo.
Events emitted
| Event | Receivers | Description |
|---|---|---|
activity.logged | camino | A billable or tracked activity has been logged (time entry from Agora ghost timer, POS customer action in Caracol, vet/hotel log in Cosmos Pet or Madriguera) and sent to Camino for CRM activity tracking |
contract.created | rito | A legal contract was created in Agora — Rito registers it against the deal or investor record for contract lifecycle tracking. |
contract.executed | rito | A legal contract was fully executed (signed by all parties) in Agora — Rito marks the deal or investor contract as executed. |
contract.expired | rito | A legal contract expired in Agora — Rito marks the contract as expired and may trigger follow-up actions. |
contract.updated | rito | A legal contract was updated in Agora — Rito syncs the changed fields on the associated deal/investor record. |
deadline.changed | camino | An existing legal deadline in Agora was updated (new date or description) — Camino mirrors for CRM timeline and reminder workflows |
deadline.created | camino | A new legal deadline was set on a matter in Agora — Camino stores it for CRM visibility and deadline alerts |
matter.assigned | camino | An attorney was assigned to a legal matter in Agora — Camino updates CRM contact-to-matter mapping for pipeline visibility |
matter.status_changed | camino | A legal matter's status changed in Agora (e.g., open → closed, active → on_hold) — Camino mirrors for CRM pipeline |
note.created | camino | Agora attached a note to a matter that should appear in Camino CRM (client communication, case update, billing note). |
Events consumed
| Event | Senders | Description |
|---|---|---|
cfdi.stamped | constanza | A CFDI invoice has been stamped by the SAT via Constanza — receiver apps attach the UUID to their local invoice record and update status. |
contract.draft_requested | rito | Rito requests Agora to draft an investment contract for an LP investor. Agora responds asynchronously with a contract URL via webhook. |
deal.won | camino | A deal was marked as won in Camino CRM — Agora creates or updates the associated matter/client record for the legal team. |
handoff.completed | baul | Generic physical handoff completed with proof. Covers document delivery, product returns, sample collection, key handoff, equipment transfer. Baul physical layer event. |
invoice.paid | colectiva | An invoice was paid — Camino marks the cobranza receivable as paid and logs the payment event on the CRM contact timeline. |
lead.qualified | camino | A lead was qualified in Camino CRM — Agora receives the qualified lead to create a new matter intake for the legal team. |
payment.chargeback_resolved | colectiva | A MercadoPago chargeback reached a terminal state. Colectiva emits this when verdict.terminal && outcome ∈ {lost, won, coverage}. Constanza uses it to post a counter-póliza and (on lost + originalCfdiUuid present) cancel the original CFDI. Canonical contract is whatever colectiva/src/lib/services/ecosystem-webhook.service.js notifyPaymentChargebackResolved emits. |
payment.refunded | colectiva, comal | A payment was refunded by Colectiva — voluntary refund initiated by a tenant app or by Colectiva ops, OR an involuntary MP-platform-side refund. Receivers branch on paymentReferenceType. For voluntary refunds with proration, isPartial=true and proration block carries period bounds. paymentLayer is the primary routing discriminator; receivers MUST check it before paymentReferenceType. |
refund.processed | (none declared) | A refund was processed in Colectiva — Agora updates the case billing record to reflect the refunded amount. |
subscription.activated | camino, colectiva | A subscription plan has been activated for a tenant — all apps that gate features behind the subscription tier update their local tier state. |
subscription.cancelled | camino, colectiva | A subscription has been cancelled — all apps that gate features behind the subscription tier update their local tier state to free/cancelled. |
subscription.changed | camino | A subscription plan has been upgraded or downgraded — receiver apps update their tier gates and feature access accordingly. |
subscription.payment_failed | camino, colectiva | A subscription payment attempt failed — receiver apps surface a payment-failed banner to the tenant operator and may restrict feature access. |
subscription.pending_cancellation | camino | A subscription cancellation was scheduled for the end of the current billing period — receiver apps surface a notice that the subscription will end soon. |
Webhook signature
Standard ecosystem HMAC-SHA256 over the raw body with a 5-minute timestamp window. See Webhooks.
Gotchas
- Trust accounting (IOLTA) has hard regulatory constraints — never commingle operating funds with trust in your adapter. Trust balances are surfaced read-only to the partner API.
- Ghost Timer events arrive as
time.loggedwithsource: "ghost_timer". If you aggregate timesheets, dedupe on(matterId, userId, startedAt)— the timer can emit multiple drafts before a final entry. - Invoices generated here emit
invoice.generated. The corresponding CFDI stamping firescfdi.stampedseparately from Constanza — wire both if you want a unified billing audit trail.