Practice Management
Partner firm APIs for client entities, time tracking, and firm-level billing.
Practice management APIs for partner firms only. Your firm must be enrolled in the partner program to call these endpoints.
Billing: Partner client tiers and monthly fees are part of the accounting-firm program and are separate from each client workspace’s prepaid credit balance on Axiomatic cloud. See Billing and credits for how cloud credits work for end customers.
Client Entities
List Client Entities
GET /api/practice/clients?firmEntityId={firmEntityId}Returns all active client entities managed by the partner firm.
Create Client Entity
POST /api/practice/clientsCreates a new entity, seeds default chart of accounts and books, links it to the partner firm, and syncs the partner firm's Stripe billing for that client (monthly fee by tier).
Request body
| Field | Type | Required | Description |
|---|---|---|---|
firmEntityId | string | Yes | Partner firm entity ID |
name | string | Yes | Client business name |
type | string | No | Entity type (llc, corp, sole_prop, etc.) |
industry | string | No | Industry classification |
tier | string | No | Partner client tier (STARTER, PROFESSIONAL, BUSINESS) for firm program pricing. Default: STARTER |
billingMode | string | No | consolidated or client_direct. Default: consolidated |
Response
{
"entity": { "id": "ent_new", "name": "Acme Corp", "...": "..." },
"link": { "id": "pcl_123", "clientTier": "STARTER", "billingMode": "consolidated", "monthlyFee": 79 }
}Invite Client User
POST /api/practice/clients/{entityId}/inviteSends an email invitation to a client user to join the entity.
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Invitee email address |
role | string | No | Role to assign (ADMIN, MEMBER, VIEWER). Default: VIEWER |
Time Tracking
List Time Entries
GET /api/practice/time?firmEntityId={firmEntityId}Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
firmEntityId | string | Yes | Partner firm entity ID |
clientEntityId | string | No | Filter by client entity |
from | string | No | Start date (ISO 8601) |
to | string | No | End date (ISO 8601) |
unbilledOnly | boolean | No | Only return unbilled entries |
Response
{
"entries": [ { "id": "te_1", "hours": 2.5, "description": "Month-end close", "..." : "..." } ],
"totalHours": 12.5,
"billableHours": 10.0
}Create Time Entry
POST /api/practice/time| Field | Type | Required | Description |
|---|---|---|---|
firmEntityId | string | Yes | Partner firm entity ID |
entityId | string | Yes | Client entity ID |
date | string | Yes | Date of work (ISO 8601) |
hours | number | Yes | Hours worked |
description | string | No | Description of work |
billable | boolean | No | Whether billable. Default: true |
rate | number | No | Hourly rate in cents |
Delete Time Entry
DELETE /api/practice/time?timeEntryId={timeEntryId}&firmEntityId={firmEntityId}Deletes a time entry. Invoiced entries cannot be deleted.
Engagements
List Engagements
GET /api/practice/engagements?firmEntityId={firmEntityId}Returns all engagements with their associated tasks.
Create Engagement
POST /api/practice/engagements| Field | Type | Required | Description |
|---|---|---|---|
firmEntityId | string | Yes | Partner firm entity ID |
entityId | string | Yes | Client entity ID |
name | string | Yes | Engagement name |
startDate | string | Yes | Start date (ISO 8601) |
type | string | No | bookkeeping, tax_prep, advisory, audit, other |
recurrence | string | No | monthly, quarterly, annual, or null |
notes | string | No | Additional notes |
Update Engagement / Complete Task
PATCH /api/practice/engagementsComplete a task:
{ "firmEntityId": "...", "taskId": "task_123" }Update engagement status:
{ "firmEntityId": "...", "engagementId": "eng_123", "status": "completed" }Billing
Get Billing Overview
GET /api/practice/billing?firmEntityId={firmEntityId}Returns partner tier, volume discount, and per-client billing breakdown.
Generate Invoice from Time Entries
POST /api/practice/billing/invoiceCreates an AR invoice from unbilled time entries for a specific client.
| Field | Type | Required | Description |
|---|---|---|---|
firmEntityId | string | Yes | Partner firm entity ID |
clientEntityId | string | Yes | Client entity ID |
timeEntryIds | string[] | Yes | Array of time entry IDs to invoice |
Response
{
"invoice": { "id": "inv_123", "total": 250000, "lineCount": 3 },
"markedEntries": 3
}Reports
Generate PDF Report
GET /api/reports/pdf?entityId={entityId}&bookId={bookId}&report={type}&from={date}&to={date}Server-side financial report generation. Returns HTML (Content-Type: text/html).
| Parameter | Type | Required | Description |
|---|---|---|---|
entityId | string | Yes | Entity ID |
bookId | string | Yes | Book ID |
report | string | Yes | balance_sheet, income_statement, or trial_balance |
from | string | Yes | Period start date |
to | string | Yes | Period end date |
Create Shareable Report Link
POST /api/reports/shareGenerates a time-limited shareable link to a report.
| Field | Type | Required | Description |
|---|---|---|---|
entityId | string | Yes | Entity ID |
reportType | string | Yes | Report type |
parameters | object | Yes | Report parameters (bookId, from, to) |
expiresInDays | number | No | Expiry in days. Default: 7 |
Response
{
"shareUrl": "https://app.axiomatic.financial/api/reports/share/tok_abc123",
"expiresAt": "2026-03-11T00:00:00Z"
}Access Shared Report
GET /api/reports/share/{token}Redirects to the rendered report if the token is valid and not expired. Increments access count.