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.

  1. 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.
  2. Create an API client and select only the scopes your integration needs.
  3. 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 scopeGrants
mcpMCP transport access — request this for any MCP client
clients:readList or get clients
entities:readList or get legal entities
tax-years:readList or get tax years
engagements:readGet engagement metadata
documents:readList document metadata
workpapers:readList workpaper metadata
review:readGet review indicators
tax:computeList and run deterministic computations
readLegacy 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 pathRequired scopeResult boundary
GET /api/v1/clientsread or clients:readOrganization clients
GET /api/v1/clients/{client_id}clients:readOne client
GET /api/v1/clients/{client_id}/entitiesentities:readClient's legal entities
GET /api/v1/entities/{entity_id}entities:readOne legal entity
GET /api/v1/entities/{entity_id}/tax-yearstax-years:readEntity's tax years
GET /api/v1/tax-years/{tax_year_id}tax-years:readOne tax year
GET /api/v1/engagements/{engagement_id}engagements:readSafe identity, period, status, and lifecycle metadata
GET /api/v1/engagements/{engagement_id}/documentsdocuments:readDocument registry metadata only
GET /api/v1/engagements/{engagement_id}/workpapersworkpapers:readWorkpaper metadata only
GET /api/v1/engagements/{engagement_id}/review-summaryreview:readPersisted review indicators, not a filing-readiness verdict
GET /api/v1/computationstax:computeBatch dependency graph and target catalogs
POST /api/v1/computations/batchtax:computeSelected batch targets and dependencies
POST /api/v1/computations/rollovers/{target}tax:computeOne 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:

SettingValue
TransportStreamable HTTP
OAuth grantclient_credentials
Token endpointhttps://api.filemark.ca/oauth2/token
Resourcehttps://api.filemark.ca
Base scopehttps://api.filemark.ca/mcp
Domain scopesOnly 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

ToolDomain scopeREST-equivalent behavior
list_clientsread or clients:readList clients
get_clientclients:readGet client
list_entitiesentities:readList a client's entities
get_entityentities:readGet entity
list_tax_yearstax-years:readList an entity's tax years
get_tax_yeartax-years:readGet tax year
get_engagementengagements:readGet safe engagement metadata
list_engagement_documentsdocuments:readList safe document metadata
list_engagement_workpapersworkpapers:readList safe workpaper metadata
get_engagement_review_summaryreview:readGet persisted review indicators
list_computationstax:computeGet computation catalog
compute_tax_schedulestax:computeRun batch computation
compute_rollovertax:computeRun 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}/documents
  • filemark://engagements/{engagement_id}/workpapers
  • filemark://engagements/{engagement_id}/review-summary
  • filemark://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

StatusMeaning
400 or 422The request or one of its parameters is invalid.
401The token is missing, invalid, expired, or unknown.
403The client is disabled or the effective scope is insufficient.
404The route or organization-scoped resource was not found.
405The HTTP method is not supported for the public resource.
409The operation conflicts with the current saved state or lifecycle state.
413The request body exceeds the 256 KiB public machine-interface limit.
429A request budget was exceeded. Respect Retry-After.
500An unexpected server error occurred.
502A required upstream service failed to complete the operation.
503Authentication 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