Authentication

Server integrations exchange a client ID and secret for access tokens using the OAuth 2.0 client_credentials grant. AI assistants and other interactive MCP hosts use delegated access to connect as a signed-in user.

Create API credentials

Creating credentials requires the owner role or the admin role with Manage developer API permission. Other workspace members can view the credential list.

  1. Sign in at app.filemark.ca and open Developer.
  2. Create an API client and select only the scopes your integration needs.
  3. Copy the client secret, which is shown once.

Store the secret in a server-side secret manager and keep it out of browser code and tools, source control, logs, URLs, and messages.

Rotate a leaked secret from Developer to replace it while keeping the client ID and scopes. Revoking a client permanently disables it and invalidates its tokens on the next request.

Get an access token

  • Set resource to https://api.filemark.ca for REST and MCP access, or https://api.filemark.ca/mcp for MCP access only. The trailing-slash form of https://api.filemark.ca is also accepted.
  • Set scope to the full scope names your integration needs, separated by spaces. Include mcp for an MCP connection.
  • Choose one authentication method, HTTP Basic or the client_id and client_secret form fields, and send each parameter once.
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/tax:compute"
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/mcp https://api.filemark.ca/tax:compute",
    },
)
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/mcp https://api.filemark.ca/tax:compute",
  }),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());
{
  "access_token": "<access-token>",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "https://api.filemark.ca/mcp https://api.filemark.ca/tax:compute"
}

Tokens last up to 60 minutes.

Token endpoint errors

A failed exchange returns {"error": "...", "error_description": "..."} with one of these OAuth 2.0 errors.

errorStatusCause
invalid_request400The form is malformed, a parameter is missing, duplicated, or unsupported, both authentication methods were sent, or the Content-Type is not application/x-www-form-urlencoded.
invalid_request413The form body exceeds 256 KiB.
invalid_client401The client ID and secret were rejected, or the client is unknown or not active.
invalid_scope400A requested scope is unpublished or has not been granted to the client.
unsupported_grant_type400The endpoint does not support the requested grant_type.
invalid_target400resource is not https://api.filemark.ca, its trailing-slash form, or https://api.filemark.ca/mcp.
temporarily_unavailable429 or 503The token request limit was reached (429) or the token service is unavailable (503). Wait the number of seconds in Retry-After before retrying.
Filemark | Authentication