Skip to main content

LegalVoice SDK

Read stored LegalVoice and MediVoice firm records through the existing customer API. The FAB's Claude Agent SDK tools call the same backend query functions; this package gives scripts and external MCP hosts access through firm API keys.

Official developer documentation: LegalVoice and MediVoice. The legalvoice-sdk package contains the Python SDK, command-line client, and optional FastMCP server. It contains no API keys, customer records, database credentials, or backend application code.

Upgrading from the original package

legalvoice-sdk is the official package name. The original voice-firm-data==0.3.1 remains available so existing integrations keep working. For new installs, use the command below. To migrate, change Python imports from voice_firm_data to legalvoice_sdk, the CLI command from firm-data to legalvoice, and the MCP executable from firm-data-mcp to legalvoice-mcp. The client methods, API-key environment variables and API behavior are unchanged. The two releases use separate Python modules and commands, so they can coexist while you migrate.

Install and authenticate

Use Python 3.10 or later:

python -m venv .venv-legalvoice
source .venv-legalvoice/bin/activate
python -m pip install --upgrade pip
python -m pip install "legalvoice-sdk[mcp]==0.3.2"

Omit [mcp] if you only need the Python client and CLI. Developer settings also provide a versioned wheel download and checksum. On Windows, activate the virtual environment with .venv-legalvoice\Scripts\activate.

Create a data export key in the product's Developer API settings. Set it privately as FIRM_DATA_API_KEY, LEGALVOICE_API_KEY, or MEDIVOICE_API_KEY. Resolution follows that order. Keys need data:read or exports:read; the server derives the firm from the key. A key cannot select a different firm through query arguments.

An API key is required; an OAuth client ID is not. The key identifies the firm (account_id, also called agency_id). The API's client_id identifies a person/client record inside that firm; use it as an optional filter when you want that client's calls, notes, tasks, or web chats. It is not a password and cannot grant access to another firm's records. legalvoice whoami reports the account and key identity; legalvoice query clients discovers client records.

Set FIRM_DATA_BASE_URL to the API origin shown in Developer settings. It defaults to https://api.legalvoice.app, the shared API default. Use the API origin, not the dashboard's domain. HTTPS is required except for localhost development. Credentials are not accepted as CLI arguments, returned in errors, or forwarded across redirects.

CLI

legalvoice whoami
legalvoice discover
legalvoice query clients --search Jane
legalvoice query members
legalvoice query web-chats --filter client_id=CLIENT_ID
legalvoice query web-chat-messages --filter widget_key=WIDGET_KEY --filter session_id=SESSION_ID
legalvoice query web-chat-tools --filter widget_key=WIDGET_KEY --filter session_id=SESSION_ID
legalvoice query activity --filter client_id=CLIENT_ID
legalvoice query calls --since 2026-09-01 --until 2026-09-08 --filter callback_requested=true
legalvoice count calls --since 2026-09-01 --until 2026-09-08 --group-by status
legalvoice query tasks --filter status=open --date-field due_on --until 2026-09-15
legalvoice query notes --filter client_id=CLIENT_ID
legalvoice query profile-notes --search Jane
legalvoice query calls --search 'car accident'
legalvoice get calls CALL_ID_OR_SID
legalvoice query notes --all > notes.jsonl

Single requests print JSON with source references and coverage metadata. Lists return has_more and next_cursor; pass --cursor CURSOR with the same filters. Grouped counts also paginate. Ungrouped count returns the exact count of all matches, regardless of --limit.

query --all streams JSONL through every page (default ceiling: 1,000 pages; configurable with --max-pages). It exits nonzero on errors, repeated/missing cursors or an exceeded page ceiling. A file written before an error is incomplete; check the exit status. Pages are live reads, so concurrent inserts or updates can shift pagination. This is not a transactional snapshot.

Dates are UTC. since is inclusive and until exclusive. For September 1–7, use --since 2026-09-01 --until 2026-09-08. Timestamps require an explicit timezone offset. Exact filters and grouping fields vary by resource; discovery lists the supported fields for the deployed schema. Search is literal, case-insensitive substring matching over listed fields, including call transcripts.

Python SDK

from legalvoice_sdk import FirmDataClient

with FirmDataClient.from_env() as firm:
    identity = firm.identity()  # account_id, scopes and enforced key/account budgets
    catalog = firm.discover()
    total = firm.query("calls", mode="count", since="2026-09-01")
    tasks = firm.query("tasks", filters={"status": "open"})
    for note in firm.iter_records("notes", filters={"client_id": "CLIENT_ID"}):
        print(note["body"], note["source_ref"])
    call = firm.get("calls", "CALL_ID")  # full transcript/content

An explicit client is FirmDataClient(api_key, base_url). Close it or use a context manager. Queries default to 25 records, maximum 250. Transcripts, metadata and document payloads are omitted from list results unless include_full_payload=True; each result lists omitted_fields. Detail requests include full content. Sensitive configuration resources always use a limited metadata projection, even in full mode.

IDs and relationships

Field Meaning
account_id The firm's existing agency_id, determined by the authenticated key
client_id The stable agency_people.id returned by clients and people; changing a name or phone does not change it
member_id A firm membership's agency_members.id
user_id The member's login identity; one login can belong to multiple firms

client_id is an alias for an existing identity, so there is no new ID backfill. Related records expose it when person_id or primary_person_id is recorded. An unlinked record has client_id: null; clients are never joined by guessing from names or phone numbers. Discovery reports each resource's client_id_field and whether it supports the client_id filter. Other relationships use the catalog's specific IDs, such as call_sid, engagement_id, run_id, and document_id.

Enforced API budgets

All developer-key requests share PostgreSQL counters across server replicas. A reservation checks and charges both the key and its account atomically, before the handler runs. Creating or rotating keys does not reset the account budget. Existing keys automatically receive the standard limits.

Budget Per UTC minute Per UTC day Concurrent requests
Standard key 120 units 12,000 units 3
Limited key preset 30 units 3,000 units 3
Account, shared by all keys 600 units 60,000 units 8

Ordinary requests cost 1 unit, queries/counts 5, discovery/export manifests 10, and CSV exports 60. These are fixed UTC minute/day windows, not rolling windows. Customer data requests have a 90-second deadline; query execution also has a 30-second database timeout. Short leases recover concurrency capacity after a worker stops unexpectedly.

Owners/admins choose a standard or limited budget when creating a key in Developer API settings. The key-creation endpoint also accepts rate_limits: {"per_minute": 30, "per_day": 3000}. Custom positive values cannot exceed the server's standard caps, including when reading stored metadata. A request costing more than a key's entire minute/day budget returns 422; limited keys must use paginated JSON instead of CSV.

An exhausted budget returns 429 with Retry-After in seconds. Responses expose Limit, Remaining, Reset (Unix seconds), Day-Limit, Day-Remaining, Account-Limit, Account-Remaining, and Cost, all prefixed with X-RateLimit-. GET /me / legalvoice whoami reports the configured limits. Failed quota storage returns 503 without executing the request. Requests rejected for missing/revoked keys do not reserve a budget; authenticated requests consume units even if their handler rejects the request.

The SDK, CLI, and MCP adapter retry 429 responses up to twice, honoring delays up to 60 seconds. A longer delay, or exhausted retries, raises FirmDataRateLimitError with status_code=429 and retry_after; the CLI exits nonzero. Python callers can set max_retries=0 to handle retries themselves and inspect client.last_rate_limits. Multi-page exports retain their incomplete-file behavior on quota exhaustion.

MCP

Install the mcp extra, then configure your MCP host to run legalvoice-mcp over stdio. The server uses the standalone FastMCP framework, pinned to 4.0.3, with from fastmcp import FastMCP and decorated tools. FastMCP owns schema generation, validation, transport and protocol handling. This package exposes local stdio transport; there is no hosted MCP URL or OAuth connector in this release.

{
  "mcpServers": {
    "legalvoice": {
      "command": "/absolute/path/to/.venv-legalvoice/bin/legalvoice-mcp",
      "env": {
        "FIRM_DATA_BASE_URL": "https://api.legalvoice.app",
        "FIRM_DATA_API_KEY": "<set your firm key privately in the host>"
      }
    }
  }
}

Use the host's private environment/secret settings where available. The placeholder must be replaced; it is not automatic shell-variable interpolation. GUI apps may require the executable's absolute path. The server writes protocol traffic to stdout and does not open a listening network port.

The three tools are:

Tool Purpose
discover_firm_data Available resources, search/filter/date/group fields and query schema
query_firm_data Search, filter, paginate or count all matching records
get_firm_record Full record details with a source reference

Try: “Show overdue open tasks grouped by owner,” “Find calls mentioning a car accident,” “Which members handle this client's work?” or “Summarize this client's web chats, notes and open tasks.” Resolve the client through clients, then use its client_id. For web chat transcripts and tool activity, query web-chat-messages and web-chat-tools with both widget_key and session_id from web-chats.

HTTP contract and coverage

All routes use the existing customer API key authentication and scopes:

  • GET /api/v1/customer/v1/data — discovery.
  • GET /api/v1/customer/v1/me — account, key scopes and budgets.
  • POST /api/v1/customer/v1/query — a read-only query body, e.g. {"resource":"tasks","filters":{"status":"open"}}.
  • GET /api/v1/customer/v1/records/{resource}/{record_id} — record detail.

The registry covers 67 named resources (including aliases). Some tables are optional and differ by deployment; discovery reports availability explicitly. Requests to unavailable resources fail instead of claiming zero records. Each registered resource also has list, detail, and CSV export routes in the Developer API catalog.

Area Resources
Clients and members Clients/people, canonical contacts and cases, members/users, identity links, client facts, client messages, client audit history
Communications and intake Calls/transcripts, intakes, web intakes, web chat sessions/messages/tool calls, email, SMS, messaging agent sessions/turns, appointments
Work and activity Saved notes, profile notes, tasks, client activity, engagements/participants/links/events, work items and their events
Documents Source/generated documents, projects, annotations, mentions, document workflows, e-sign envelopes/packages, knowledge sources/text chunks, extraction templates/runs
Automation and campaigns Automations/dispatches, workflow definitions/runs/node runs/events/artifacts/human tasks, campaigns/runs/recipients/events/timeline
Administration Phone numbers, departments, agent profiles/configuration, intake forms, integration metadata, webhook delivery history, audit events, usage and billing periods

Activity and event feeds expose persisted history. They do not imply that every historical UI click or unrecorded action was captured, and this release does not add a universal activity recorder.

notes contains durable team notes; profile-notes contains nonempty agency_people.metadata.contact_notes. These are separate feeds, matching the two sources in the dashboard. people contains dashboard person IDs; contacts uses the canonical contact store when present and falls back to people only when that table is absent. Do not add overlapping resource counts together as unique clients or intakes.

These tools expose registered, stored firm data, not arbitrary database tables, SQL, provider credentials, or every record in an external CRM. Live external case data continues through the existing connected CRM tools. The FAB's chat controls can disable the new tools with the firm-data/recent-context groups; they remain available in review-only mode because they do not mutate records.

Distribution and license

Install from PyPI or the versioned download in Developer settings. The package uses a proprietary SDK license, not an open-source license. Authorized commercial integrations are permitted under the included LICENSE; standalone redistribution and publication of modified SDK versions require written permission. Third-party dependencies keep their own licenses.

The SDK sends requests only to the API origin configured by the developer or MCP host. Use an API origin you trust: the configured origin receives your firm API key. HTTPS certificate verification is enabled; redirects and environment proxy discovery are disabled. No telemetry is implemented by this SDK.

The MCP host may send returned firm data to its selected model provider. Use a host and provider approved for the data you access. Model instructions cannot supply a different API key, account, or API origin through these tools.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

legalvoice_sdk-0.3.2.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

legalvoice_sdk-0.3.2-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

Details for the file legalvoice_sdk-0.3.2.tar.gz.

File metadata

  • Download URL: legalvoice_sdk-0.3.2.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.9

File hashes

Hashes for legalvoice_sdk-0.3.2.tar.gz
Algorithm Hash digest
SHA256 353342f26a1fb5a43b31571d4acfc2bd2c9233e7f112ccda0baa9e167e476600
MD5 ae2df04fcbfa822e25723a4357739c46
BLAKE2b-256 a72e7e0109516b3938372f98be235c975a3a1e97b8a34bfc61f12bd861dfcbcf

See more details on using hashes here.

File details

Details for the file legalvoice_sdk-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: legalvoice_sdk-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 13.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.9

File hashes

Hashes for legalvoice_sdk-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0cc2065fb4a3e08dc0cf09f3b56525a0812bfa36c1d6fcfd25bcb3b3bb6cf894
MD5 9ac1ec62a6eec5a02f4f5d05b3c047ae
BLAKE2b-256 fe927362ff1fc186989f06aeebdc51ea0285f6302d84dc8c558a2f651aa0f4e5

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.2 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page