Quickstart
You need a Filemark workspace where you are an owner, or an admin with the Manage developer API permission; only those roles can create API credentials.
1. Create API credentials
Create an API client with the tax:compute and clients:read scopes, and copy the secret when it is shown.
export FILEMARK_CLIENT_ID="<client-id>"
export FILEMARK_CLIENT_SECRET="<client-secret>"2. Get an access token
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/tax:compute https://api.filemark.ca/clients:read"import os
import requests
FILEMARK_CLIENT_ID = os.environ["FILEMARK_CLIENT_ID"]
FILEMARK_CLIENT_SECRET = os.environ["FILEMARK_CLIENT_SECRET"]
response = requests.post(
"https://api.filemark.ca/oauth2/token",
auth=(FILEMARK_CLIENT_ID, FILEMARK_CLIENT_SECRET),
data={
"grant_type": "client_credentials",
"resource": "https://api.filemark.ca",
"scope": "https://api.filemark.ca/tax:compute https://api.filemark.ca/clients:read",
},
)
response.raise_for_status()
print(response.json())const FILEMARK_CLIENT_ID = process.env.FILEMARK_CLIENT_ID;
const FILEMARK_CLIENT_SECRET = process.env.FILEMARK_CLIENT_SECRET;
const response = await fetch("https://api.filemark.ca/oauth2/token", {
method: "POST",
headers: {
Authorization: `Basic ${Buffer.from(`${FILEMARK_CLIENT_ID}:${FILEMARK_CLIENT_SECRET}`).toString("base64")}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
grant_type: "client_credentials",
resource: "https://api.filemark.ca",
scope: "https://api.filemark.ca/tax:compute https://api.filemark.ca/clients:read",
}),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());{
"access_token": "<access-token>",
"token_type": "Bearer",
"expires_in": 900,
"scope": "https://api.filemark.ca/tax:compute https://api.filemark.ca/clients:read"
}export FILEMARK_ACCESS_TOKEN="<access-token>"Mint a new token when expires_in runs out.
3. Read the computation catalog
curl https://api.filemark.ca/api/v1/computations \
--header "Authorization: Bearer $FILEMARK_ACCESS_TOKEN"import os
import requests
FILEMARK_ACCESS_TOKEN = os.environ["FILEMARK_ACCESS_TOKEN"]
response = requests.get(
"https://api.filemark.ca/api/v1/computations",
headers={
"Authorization": f"Bearer {FILEMARK_ACCESS_TOKEN}",
},
)
response.raise_for_status()
print(response.json())const FILEMARK_ACCESS_TOKEN = process.env.FILEMARK_ACCESS_TOKEN;
const response = await fetch("https://api.filemark.ca/api/v1/computations", {
headers: {
Authorization: `Bearer ${FILEMARK_ACCESS_TOKEN}`,
},
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());{
"data": {
"batchTargets": ["schedule1", "schedule3", "schedule8", "schedule24", "part_i_tax"],
"batchDependencies": {
"schedule8": ["schedule23", "schedule24", "schedule6"]
},
"rolloverTargets": ["section-22", "section-86"]
}
}The real response lists every published target; this excerpt is abbreviated. batchDependencies names the targets that run automatically with the one you request.
4. Run a computation
This runs entirely from the inputs you send, so it works before your workspace holds a single client.
curl --request POST https://api.filemark.ca/api/v1/computations/batch \
--header "Authorization: Bearer $FILEMARK_ACCESS_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"compute": [
"schedule24"
],
"inputs": {
"taxYear": 2025,
"schedule24": {
"filingTriggers": [
"incorporation"
],
"operationCode": "01",
"predecessors": [],
"subsidiaries": []
}
}
}'import os
import requests
FILEMARK_ACCESS_TOKEN = os.environ["FILEMARK_ACCESS_TOKEN"]
response = requests.post(
"https://api.filemark.ca/api/v1/computations/batch",
headers={
"Authorization": f"Bearer {FILEMARK_ACCESS_TOKEN}",
},
json={
"compute": [
"schedule24",
],
"inputs": {
"taxYear": 2025,
"schedule24": {
"filingTriggers": [
"incorporation",
],
"operationCode": "01",
"predecessors": [],
"subsidiaries": [],
},
},
},
)
response.raise_for_status()
print(response.json())const FILEMARK_ACCESS_TOKEN = process.env.FILEMARK_ACCESS_TOKEN;
const response = await fetch("https://api.filemark.ca/api/v1/computations/batch", {
method: "POST",
headers: {
Authorization: `Bearer ${FILEMARK_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"compute": [
"schedule24"
],
"inputs": {
"taxYear": 2025,
"schedule24": {
"filingTriggers": [
"incorporation"
],
"operationCode": "01",
"predecessors": [],
"subsidiaries": []
}
}
}),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());{
"data": {
"results": {
"schedule24": {
"ready": false,
"provisional": false,
"warnings": []
}
}
},
"computeVersion": "<string>",
"engineSchemaVersion": "<string>",
"ratesVersion": "<string>",
"timestamp": "2026-07-14T12:00:00Z"
}Each result also carries the target's own output cells, listed under schedule24. To try a computation before wiring up credentials, sign in at app.filemark.ca and open API sandbox: it runs the same targets from your browser session and copies out the equivalent curl command.
5. List your clients
curl --get https://api.filemark.ca/api/v1/clients \
--header "Authorization: Bearer $FILEMARK_ACCESS_TOKEN" \
--data-urlencode "limit=5"import os
import requests
FILEMARK_ACCESS_TOKEN = os.environ["FILEMARK_ACCESS_TOKEN"]
response = requests.get(
"https://api.filemark.ca/api/v1/clients",
headers={
"Authorization": f"Bearer {FILEMARK_ACCESS_TOKEN}",
},
params={
"limit": "5",
},
)
response.raise_for_status()
print(response.json())const FILEMARK_ACCESS_TOKEN = process.env.FILEMARK_ACCESS_TOKEN;
const url = new URL("https://api.filemark.ca/api/v1/clients");
url.searchParams.set("limit", "5");
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${FILEMARK_ACCESS_TOKEN}`,
},
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());{
"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": 5,
"offset": 0,
"total": 1,
"hasMore": false
}
}Entities and tax years hang off the client; see Definitions.
Next steps
- Computation reference lists every target's cells and an example request.
- Run computations adds vendor handoff, strict contracts, and rollovers.
- Scopes and rate limits govern what a token may do and how often.
- Error codes explains the per-field
error.detailsa refused computation returns. - Delegated access connects an AI assistant or other MCP host as a signed-in user.