Filemark developer docs
Read supported organization and engagement metadata and run Filemark's tax computations from your own systems, over REST or MCP.
Overview
The published v1.1 API is reads plus deterministic computations, with no tenant-state writes — reads return metadata only, never document bytes, workpaper contents, trial-balance data, or tax-return payloads. Treat the live OpenAPI schema and MCP discovery as the authority for what's available.
Computations are fully stateless: every call computes only from the input cells you submit and returns the target's computed cells, warnings, and gates. The computation target reference lists every published target's input and output cells, so you can drive the engine entirely from your own trial-balance and workpaper systems.
Get access
Create your API credentials from the Filemark app.
- Sign in at app.filemark.ca and open Developer. Every signed-in role can open the gateway; creating credentials is restricted to workspace owners and admins who hold the developer-management permission.
- Create an API client and select only the scopes your integration needs.
- Copy the client secret when it's shown. It appears once and can't be retrieved later.
Store the secret in a server-side secret manager. Never put it in browser code, browser-based tools like the interactive REST reference, source control, logs, URLs, or support messages. You don't send an organization ID anywhere — Filemark derives your organization from the authenticated client.
Scopes
Scopes go on the wire fully qualified, prefixed with https://api.filemark.ca/ — the short name clients:read is sent as https://api.filemark.ca/clients:read.
| Short scope | Grants |
|---|---|
mcp | MCP transport access — request this for any MCP client |
clients:read | List or get clients |
entities:read | List or get legal entities |
tax-years:read | List or get tax years |
engagements:read | Get engagement metadata |
documents:read | List document metadata |
workpapers:read | List workpaper metadata |
review:read | Get review indicators |
tax:compute | List and run deterministic computations |
read | Legacy alias that only lists clients — prefer clients:read |
The authorization server also defines *:write, exports, portal, integrations, and admin scopes for future capabilities; they grant nothing today. The Developer credential form does not offer unpublished mutation or external-effect scopes, and new-client creation rejects broad unallocated reservations, so don't build against them.
Get an access token
Exchange your client ID and secret with OAuth 2.0 client_credentials. resource is required and must match exactly. Omit mcp for a REST-only integration.
curl --request POST \
--url https://api.filemark.ca/oauth2/token \
--user "$FILEMARK_CLIENT_ID:$FILEMARK_CLIENT_SECRET" \
--header "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "resource=https://api.filemark.ca" \
--data-urlencode "scope=https://api.filemark.ca/mcp https://api.filemark.ca/clients:read https://api.filemark.ca/entities:read https://api.filemark.ca/tax-years:read"
A successful exchange returns:
{
"access_token": "<access-token>",
"token_type": "Bearer",
"expires_in": 900,
"scope": "https://api.filemark.ca/mcp https://api.filemark.ca/clients:read https://api.filemark.ca/entities:read https://api.filemark.ca/tax-years:read"
}
Tokens last up to 15 minutes. This endpoint issues the only token REST and MCP accept.
Supported REST operations
Send the access token in the Authorization: Bearer header. The scope column uses short names; send the fully qualified form.
| Method and path | Required scope | Result boundary |
|---|---|---|
GET /api/v1/clients | read or clients:read | Organization clients |
GET /api/v1/clients/{client_id} | clients:read | One client |
GET /api/v1/clients/{client_id}/entities | entities:read | Client's legal entities |
GET /api/v1/entities/{entity_id} | entities:read | One legal entity |
GET /api/v1/entities/{entity_id}/tax-years | tax-years:read | Entity's tax years |
GET /api/v1/tax-years/{tax_year_id} | tax-years:read | One tax year |
GET /api/v1/engagements/{engagement_id} | engagements:read | Safe identity, period, status, and lifecycle metadata |
GET /api/v1/engagements/{engagement_id}/documents | documents:read | Document registry metadata only |
GET /api/v1/engagements/{engagement_id}/workpapers | workpapers:read | Workpaper metadata only |
GET /api/v1/engagements/{engagement_id}/review-summary | review:read | Persisted review indicators, not a filing-readiness verdict |
GET /api/v1/computations | tax:compute | Batch dependency graph and target catalogs |
POST /api/v1/computations/batch | tax:compute | Selected batch targets and dependencies |
POST /api/v1/computations/rollovers/{target} | tax:compute | One rollover, reorganization, or screening result |
An engagement ID is the UUID of the corresponding tax-year engagement. Both unknown IDs and IDs outside your organization return 404.
Pagination
GET /clients, /engagements/{id}/documents, and /engagements/{id}/workpapers use bounded offset pagination. limit defaults to 50 and accepts 1 through 200. offset is zero-based and accepts 0 through 100,000. Follow pagination.hasMore and advance offset by the number of returned rows.
The client-to-entity and entity-to-tax-year collections use opaque keyset cursors. Pass the returned pagination.nextCursor unchanged as the next request's cursor; do not decode it or reuse it under a different parent resource. A null nextCursor marks the final page.
curl --get https://api.filemark.ca/api/v1/clients \
--header "Authorization: Bearer $FILEMARK_ACCESS_TOKEN" \
--data-urlencode "limit=50" \
--data-urlencode "offset=0"
{
"data": [
{
"id": "3f1a5b2c-9d4e-4f8a-b1c2-0a1b2c3d4e5f",
"name": "Acme Holdings Inc.",
"createdAt": "2026-07-14T12:00:00Z",
"updatedAt": "2026-07-14T12:00:00Z"
}
],
"pagination": {
"limit": 50,
"offset": 0,
"total": 1,
"hasMore": false
}
}
Deterministic computation
GET /api/v1/computations is the runtime catalog: the currently public batch targets, their public dependency graph, and the available rollover, reorganization, and screening targets. The catalog is the authority on what is currently available.
Submit one to 100 unique batch target names and an explicit four-digit inputs.taxYear; dependencies run automatically. The default v1 contract accepts a bounded JSON input object rather than per-target JSON Schemas: global request-size, nesting, list, and numeric bounds apply, and a field the outer object accepts is not necessarily supported by a given target — treat 4xx responses and returned warnings or provisional state as authoritative. The computation target reference documents each target's accepted input cells and returned output cells.
Optionally, a batch or rollover request may add the payloadContract selector — an exact boundaryProfileId plus payloadSchemaVersion pair, published per target in the computation target reference — to opt one target into its strict profile. A strict batch request names exactly one direct target; the request is validated against that target's versioned input schema before execution and the result against its output schema after, so a contract mismatch is a 400 instead of a silently divergent result. Omit payloadContract to stay on the default boundary; null is not valid.
curl --request POST https://api.filemark.ca/api/v1/computations/batch \
--header "Authorization: Bearer $FILEMARK_ACCESS_TOKEN" \
--header "Content-Type: application/json" \
--data '{"compute":["schedule3"],"inputs":{"taxYear":2026}}'
Run one catalogued rollover target by path:
curl --request POST https://api.filemark.ca/api/v1/computations/rollovers/section-86 \
--header "Authorization: Bearer $FILEMARK_ACCESS_TOKEN" \
--header "Content-Type: application/json" \
--data '{"inputs":{}}'
Batch and rollover execution responses include data, computeVersion, engineSchemaVersion, and timestamp; the computation-catalog response contains its data catalog only. Computation calls have no engagement_id and never hydrate or persist saved return data — every computation runs only from the inputs you submit, so the API cannot return a client's populated Schedule X.
Connect over MCP
Filemark exposes stateless Streamable HTTP MCP at:
https://api.filemark.ca/mcp
Configure your MCP client with these values:
| Setting | Value |
|---|---|
| Transport | Streamable HTTP |
| OAuth grant | client_credentials |
| Token endpoint | https://api.filemark.ca/oauth2/token |
| Resource | https://api.filemark.ca |
| Base scope | https://api.filemark.ca/mcp |
| Domain scopes | Only those required by the selected tools/resources |
The client must support the MCP OAuth client credentials extension. Hosts that require an interactive PKCE or dynamic-client-registration flow aren't compatible. Keep the client ID and secret in the host's secure credential store.
Published MCP tools
| Tool | Domain scope | REST-equivalent behavior |
|---|---|---|
list_clients | read or clients:read | List clients |
get_client | clients:read | Get client |
list_entities | entities:read | List a client's entities |
get_entity | entities:read | Get entity |
list_tax_years | tax-years:read | List an entity's tax years |
get_tax_year | tax-years:read | Get tax year |
get_engagement | engagements:read | Get safe engagement metadata |
list_engagement_documents | documents:read | List safe document metadata |
list_engagement_workpapers | workpapers:read | List safe workpaper metadata |
get_engagement_review_summary | review:read | Get persisted review indicators |
list_computations | tax:compute | Get computation catalog |
compute_tax_schedules | tax:compute | Run batch computation |
compute_rollover | tax:compute | Run one rollover target |
All 13 tools are annotated read-only, non-destructive, and idempotent.
compute_tax_schedules and compute_rollover accept the same optional payloadContract selector as their REST counterparts, with identical strict-profile semantics — validation before execution, fail-closed result validation after, and the same version pinning. The computation target reference applies to both transports.
Published MCP resources
Each resource enforces the same domain scope and organization boundary as its corresponding tool.
filemark://clients/{client_id}filemark://entities/{entity_id}filemark://tax-years/{tax_year_id}filemark://engagements/{engagement_id}filemark://engagements/{engagement_id}/documentsfilemark://engagements/{engagement_id}/workpapersfilemark://engagements/{engagement_id}/review-summaryfilemark://computations/catalog
The document and workpaper resources return only their first bounded metadata page. Use the corresponding list tool when you need explicit pagination controls.
Rate limits
REST and MCP share a budget of 60 non-computation-domain read requests per rolling minute per client. Computation-domain access has a separate shared budget of 30 requests per rolling minute per client, covering catalog access (GET /api/v1/computations, list_computations, and the catalog resource) as well as batch and rollover execution.
A shared pre-authentication budget of 90 requests per rolling minute per source IP covers OAuth token requests plus REST and MCP authentication work. Token minting is separately limited to 30 attempts per rolling minute per verified client across source IPs. Overall traffic from a single source IP is limited to 500 requests per five minutes. Request bodies are limited to 256 KiB.
Error codes
| Status | Meaning |
|---|---|
400 or 422 | The request or one of its parameters is invalid. |
401 | The token is missing, invalid, expired, or unknown. |
403 | The client is disabled or the effective scope is insufficient. |
404 | The route or organization-scoped resource was not found. |
405 | The HTTP method is not supported for the public resource. |
409 | The operation conflicts with the current saved state or lifecycle state. |
413 | The request body exceeds the 256 KiB public machine-interface limit. |
429 | A request budget was exceeded. Respect Retry-After. |
500 | An unexpected server error occurred. |
502 | A required upstream service failed to complete the operation. |
503 | Authentication or a required service is temporarily unavailable. Respect Retry-After when present. |
For MCP tool calls, authenticated read/compute budget exhaustion is returned as a tool error with retry guidance. Transport or authentication-budget exhaustion can instead be returned as HTTP 429.
Public REST responses include an X-Request-Id. Include that value when asking Filemark to investigate a failed request. Do not include credentials or access tokens.
Reference
- Computation target reference — every published target's input and output cells
- Interactive REST reference
- OpenAPI 3.1 schema
- OAuth authorization-server metadata
- Public signing keys
- MCP protected-resource metadata
- Filemark status