Skip to main content
A workpaper is the workbook or bundled packet that captures a client’s tax work: the editable tax_workpaper.xlsx for a business return, or a generated bundle (PDF, leadsheets, forms, checklist, source documents) assembled from the binder. The workpaper API covers three operations:
  1. Save an edited xlsx workbook back to the client’s git-backed file store (saveTaxWorkpaperXlsx).
  2. Generate a bundled workpaper download rendered server-side from the binder (generateWorkpaperBundle plus checkWorkpaperGenerationStatus).
  3. Translate a return into a workpaper via a background task (triggerWorkpaperTranslate), and list the templates available for a given return type (workpaperTemplates).
All workpaper operations are reached through the me query resolved as a WorkspaceUser (for the Workspace.workpaperTemplates and Workspace.checkWorkpaperGenerationStatus reads) or are top-level mutations. They require a workspaceToken (see Authentication). All requests go to:
https://router.apps.filed.com/graphql
There is no top-level workpapers query. The two read fields (workpaperTemplates and checkWorkpaperGenerationStatus) live on the Workspace type, so you read them through me { ... on WorkspaceUser { workspace { ... } } }. The workspaceToken already identifies the workspace.

Save a tax workpaper xlsx

saveTaxWorkpaperXlsx commits an edited xlsx workbook back to the client’s git-backed file store as tax_workpaper.xlsx. The workbook is sent as a base64-encoded .xlsx payload. The mutation returns a ClientCommit describing the new git commit.
The web app uses this as an autosave for the in-browser workpaper editor (an exceljs workbook). The summary argument names the cell that was just edited (for example Trial Balance!B12) and becomes part of the git commit message.
mutation SaveTaxWorkpaperXlsx($input: SaveTaxWorkpaperXlsxInput!) {
  saveTaxWorkpaperXlsx(input: $input) {
    sha
    shortSha
    message
    committedAt
    author {
      kind
      name
      email
      userId
      agentName
    }
    parents
    files {
      path
      status
      additions
      deletions
      renamedFrom
    }
    taskId
    runId
  }
}

Input: SaveTaxWorkpaperXlsxInput

input SaveTaxWorkpaperXlsxInput {
  clientId: ID!
  xlsxBase64: String!
  summary: String
}
clientId
ID!
required
The client whose tax_workpaper.xlsx you are saving.
xlsxBase64
String!
required
The full xlsx workbook, base64-encoded. The server writes this verbatim to tax_workpaper.xlsx in the client’s file store.
summary
String
Optional. A short summary of the edit (for example the cell coordinate that changed). Becomes part of the git commit message.

Returns: ClientCommit!

A ClientCommit is the git commit the AI service recorded for the write. The same type is returned by other git-backed writes (updateSubDocumentField, revertClientCommit).
type ClientCommit {
  sha: String!
  shortSha: String!
  author: GitAuthor!
  committedAt: String!
  message: String!
  parents: [String!]!
  files: [GitFileChange!]!
  taskId: String
  runId: String
}

type GitAuthor {
  kind: GitAuthorKind!
  name: String!
  email: String!
  userId: ID
  agentName: String
}

type GitFileChange {
  path: String!
  status: GitChangeStatus!
  additions: Int!
  deletions: Int!
  renamedFrom: String
}

enum GitAuthorKind {
  USER
  AGENT
  SYSTEM
}

enum GitChangeStatus {
  ADDED
  MODIFIED
  DELETED
  RENAMED
  COPIED
}
sha
String!
The full commit SHA.
shortSha
String!
The abbreviated commit SHA.
author
GitAuthor!
Who made the commit. kind is USER for a workspace user, AGENT for an automated agent, or SYSTEM for a system-level write.
committedAt
String!
ISO timestamp when the commit was recorded.
message
String!
The commit message (includes the summary you passed in, when supplied).
parents
[String!]!
Parent commit SHAs. Empty for the initial commit.
files
[GitFileChange!]!
Files changed by this commit. For saveTaxWorkpaperXlsx this is the tax_workpaper.xlsx row.
taskId
String
The task ID associated with the write, when the commit was produced by a background task. null for direct user edits.
runId
String
The run ID associated with the write, when relevant. null for direct user edits.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation SaveTaxWorkpaperXlsx($input: SaveTaxWorkpaperXlsxInput!) { saveTaxWorkpaperXlsx(input: $input) { sha shortSha message committedAt author { kind name email userId agentName } parents files { path status additions deletions renamedFrom } taskId runId } }",
    "variables": {
      "input": {
        "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
        "xlsxBase64": "UEsDBBQACAgIAAAAAAAAAAAAAAAAAAAAAAA=",
        "summary": "Trial Balance!B12"
      }
    }
  }'
{
  "data": {
    "saveTaxWorkpaperXlsx": {
      "sha": "7c4d5e6f7081901a2b3c4d5e6f7081901a2b3c4d",
      "shortSha": "7c4d5e6",
      "message": "Edit Trial Balance!B12",
      "committedAt": "2026-07-05T14:08:22.000Z",
      "author": {
        "kind": "USER",
        "name": "Jane Preparer",
        "email": "jane@example-firm.com",
        "userId": "019f0fb6-3001-7900-b7bc-0d11288504b1",
        "agentName": null
      },
      "parents": [
        "3d5e6f7081901a2b3c4d5e6f7081901a2b3c4d5e"
      ],
      "files": [
        {
          "path": "tax_workpaper.xlsx",
          "status": "MODIFIED",
          "additions": 0,
          "deletions": 0,
          "renamedFrom": null
        }
      ],
      "taskId": null,
      "runId": null
    }
  }
}

Generate a workpaper bundle

generateWorkpaperBundle queues a server-side render that assembles a bundled workpaper download (PDF, leadsheets, forms, checklist, source documents) from the binder. It returns a WorkpaperRenderJob carrying the workflowExecutionId you poll with checkWorkpaperGenerationStatus. The bundle’s table of contents and section order is driven by orderedGroups: a list of buckets, each containing categories, each containing the subdocument IDs to include. This mirrors the binder sidebar outline.
mutation GenerateWorkpaperBundle($input: GenerateWorkpaperBundleInput!) {
  generateWorkpaperBundle(input: $input) {
    workflowExecutionId
    status
  }
}

Input: GenerateWorkpaperBundleInput

input GenerateWorkpaperBundleInput {
  binderId: ID!
  orderedGroups: [WorkpaperBucketGroupInput!]!
  clientName: String
  includePdf: Boolean
  includeLeadsheets: Boolean
  leadsheetsFormat: LeadsheetsExportFormat
  includeForms: Boolean
  includeChecklist: Boolean
  includeSourceDocs: Boolean
}

input WorkpaperBucketGroupInput {
  bucketLabel: String
  categories: [WorkpaperCategoryGroupInput!]!
}

input WorkpaperCategoryGroupInput {
  category: String!
  subdocumentIds: [ID!]!
}
binderId
ID!
required
The client’s binder ID (read it from me { ... on WorkspaceUser { workspace { clients(filters: { ids: [$clientId] }) { binder { id } } } } }, see Binder).
orderedGroups
[WorkpaperBucketGroupInput!]!
required
The bucket-to-category-to-subdocument outline that drives the bundle’s section order and PDF TOC. Each entry has a bucketLabel and a list of categories; each category has a category label and the subdocumentIds to include.
clientName
String
Optional. The client’s display name, used to set the download filename (for example Filed workpaper - Jane Taxpayer.pdf).
includePdf
Boolean
When true, render a combined PDF in the bundle.
includeLeadsheets
Boolean
When true, include the client’s leadsheets in the bundle, exported in the format set by leadsheetsFormat.
leadsheetsFormat
LeadsheetsExportFormat
The leadsheets export format: EXCEL or CSV (see Leadsheets and review). Only meaningful when includeLeadsheets is true.
includeForms
Boolean
When true, include the client’s forms in the bundle.
includeChecklist
Boolean
When true, include the binder checklist in the bundle.
includeSourceDocs
Boolean
When true, include the binder’s source documents in the bundle.

Returns: WorkpaperRenderJob!

type WorkpaperRenderJob {
  workflowExecutionId: ID!
  status: WorkpaperRenderStatus!
}

enum WorkpaperRenderStatus {
  RUNNING
  COMPLETED
  FAILED
}
workflowExecutionId
ID!
The render job’s workflow execution ID. Pass it to checkWorkpaperGenerationStatus to poll for completion and the download URL.
status
WorkpaperRenderStatus!
The render status: RUNNING while the bundle is being rendered, COMPLETED when the download is ready, or FAILED if the render errored. Immediately after generateWorkpaperBundle returns, this is RUNNING.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation GenerateWorkpaperBundle($input: GenerateWorkpaperBundleInput!) { generateWorkpaperBundle(input: $input) { workflowExecutionId status } }",
    "variables": {
      "input": {
        "binderId": "018f9c2a-4b6f-7a10-b2c4-9e8d7f6a5b4d",
        "orderedGroups": [
          {
            "bucketLabel": "Income",
            "categories": [
              {
                "category": "1099s",
                "subdocumentIds": [
                  "018f9c2a-7b1e-7c3d-9a4e-2f6b1c8d0e5a",
                  "018f9c2a-7c3d-7c3d-9a4e-2f6b1c8d2f7b"
                ]
              }
            ]
          }
        ],
        "clientName": "Jane Taxpayer",
        "includePdf": true,
        "includeLeadsheets": true,
        "leadsheetsFormat": "EXCEL",
        "includeForms": true,
        "includeChecklist": true,
        "includeSourceDocs": false
      }
    }
  }'
{
  "data": {
    "generateWorkpaperBundle": {
      "workflowExecutionId": "018f9c2c-3d4e-7f50-9b66-7f7082901234",
      "status": "RUNNING"
    }
  }
}

Check a bundle render status

checkWorkpaperGenerationStatus is a Workspace field that returns the current state of a workpaper render job. Poll it with the workflowExecutionId returned by generateWorkpaperBundle until status is COMPLETED (then read downloadUrl.url) or FAILED (then read errorMessage).
query CheckWorkpaperGenerationStatus($workflowExecutionId: ID!) {
  me {
    ... on WorkspaceUser {
      id
      workspace {
        id
        checkWorkpaperGenerationStatus(workflowExecutionId: $workflowExecutionId) {
          workflowExecutionId
          status
          downloadUrl {
            filePath
            url
          }
          generatedAt
          errorMessage
        }
      }
    }
  }
}

Arguments

workflowExecutionId
ID!
required
The render job’s workflow execution ID (from generateWorkpaperBundle.workflowExecutionId).

Returns: WorkpaperRender!

type WorkpaperRender {
  workflowExecutionId: ID!
  status: WorkpaperRenderStatus!
  downloadUrl: SignedPath
  generatedAt: String
  errorMessage: String
}

type SignedPath {
  filePath: String!
  url: String!
}
workflowExecutionId
ID!
The render job’s workflow execution ID.
status
WorkpaperRenderStatus!
RUNNING, COMPLETED, or FAILED (see WorkpaperRenderStatus).
downloadUrl
SignedPath
The signed download URL for the rendered bundle. Present only when status is COMPLETED. SignedPath is { filePath, url }; the url is the one you fetch (or hand to the browser) to download the bundle. null while the render is running or if it failed.
generatedAt
String
ISO timestamp when the render completed. null while RUNNING or FAILED.
errorMessage
String
The error message when status is FAILED. null otherwise.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "query CheckWorkpaperGenerationStatus($workflowExecutionId: ID!) { me { ... on WorkspaceUser { id workspace { id checkWorkpaperGenerationStatus(workflowExecutionId: $workflowExecutionId) { workflowExecutionId status downloadUrl { filePath url } generatedAt errorMessage } } } } }",
    "variables": {
      "workflowExecutionId": "018f9c2c-3d4e-7f50-9b66-7f7082901234"
    }
  }'
{
  "data": {
    "me": {
      "id": "019f0fb6-37b1-7800-b7bc-0d11288504b1",
      "workspace": {
        "id": "019f0fb6-3001-7900-b7bc-0d11288504b1",
        "checkWorkpaperGenerationStatus": {
          "workflowExecutionId": "018f9c2c-3d4e-7f50-9b66-7f7082901234",
          "status": "COMPLETED",
          "downloadUrl": {
            "filePath": "workpaper-bundles/018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c/2026-07-05.zip",
            "url": "https://signed.example.com/workpaper-bundles/018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c/2026-07-05.zip?token=..."
          },
          "generatedAt": "2026-07-05T14:10:11.000Z",
          "errorMessage": null
        }
      }
    }
  }
}
The web app polls checkWorkpaperGenerationStatus every 1500ms with a hard timeout of 5 minutes, and on COMPLETED opens downloadUrl.url in a new tab. Mirror that pattern: poll on a short interval, stop on COMPLETED or FAILED, and treat a missing downloadUrl on COMPLETED as a failure.
This poll pattern is distinct from the Task polling pattern. Workpaper renders use a workflowExecutionId and the WorkpaperRenderStatus enum (RUNNING, COMPLETED, FAILED) on a WorkpaperRender shape returned by Workspace.checkWorkpaperGenerationStatus. They do not use the Task / TaskStatus type, the clients.tasks list, or TaskResult unions. Do not conflate the two: a workpaper render is not a Task and cannot be read through tasks(type:, status:).

Trigger a workpaper translation

triggerWorkpaperTranslate kicks off a background translation task that produces a workpaper for a client. It returns a TriggerTaskResult carrying the taskId you poll through the standard Task polling pattern (unlike the bundle render above, the translate flow is a real Task).
As of this writing, triggerWorkpaperTranslate and workpaperTemplates are not yet wired into the web app’s surface code (they exist only in the generated GraphQL types). They are documented here from the live schema for completeness. If you build against them, verify the behavior end to end against your own workspace before relying on a specific shape.
mutation TriggerWorkpaperTranslate($input: TriggerWorkpaperTranslateInput!) {
  triggerWorkpaperTranslate(input: $input) {
    taskId
  }
}

Input: TriggerWorkpaperTranslateInput

input TriggerWorkpaperTranslateInput {
  clientId: ID!
  returnType: ReturnType!
  sourceTaskType: String
  sourceRunId: ID
  templateName: String
}

enum ReturnType {
  F1040
  F1041
  F1065
  F1120
  F1120S
  F990
}
clientId
ID!
required
The client to translate a workpaper for.
returnType
ReturnType!
required
The return form to target: F1040, F1041, F1065, F1120, F1120S, or F990 (see clients).
sourceTaskType
String
Optional. The task type that produced the source data, when you are translating from the output of a prior run.
sourceRunId
ID
Optional. The run ID of the source run, when relevant.
templateName
String
Optional. A specific template to apply. List the available templates for a return type with workpaperTemplates.

Returns: TriggerTaskResult!

type TriggerTaskResult {
  taskId: ID!
}
taskId
ID!
The background task ID. Poll me { ... on WorkspaceUser { workspace { clients(filters: { ids: [$clientId] }) { tasks(type: ..., limit: 1) { id status } } } } } until status is COMPLETED or FAILED. See Tasks for the polling pattern and the TaskResult union.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation TriggerWorkpaperTranslate($input: TriggerWorkpaperTranslateInput!) { triggerWorkpaperTranslate(input: $input) { taskId } }",
    "variables": {
      "input": {
        "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
        "returnType": "F1120",
        "templateName": "default"
      }
    }
  }'
{
  "data": {
    "triggerWorkpaperTranslate": {
      "taskId": "018f9c2c-4e5f-7f60-9c77-8082901234ab"
    }
  }
}

List workpaper templates

workpaperTemplates is a Workspace field that returns the list of workpaper template names available for a given return type. Pass a template name as templateName to triggerWorkpaperTranslate.
query WorkpaperTemplates($returnType: ReturnType!) {
  me {
    ... on WorkspaceUser {
      id
      workspace {
        id
        workpaperTemplates(returnType: $returnType)
      }
    }
  }
}

Arguments

returnType
ReturnType!
required
The return form to list templates for: F1040, F1041, F1065, F1120, F1120S, or F990.

Returns: [String!]!

A list of template name strings. Pass any one of them as templateName to triggerWorkpaperTranslate.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "query WorkpaperTemplates($returnType: ReturnType!) { me { ... on WorkspaceUser { id workspace { id workpaperTemplates(returnType: $returnType) } } } }",
    "variables": { "returnType": "F1120" }
  }'
{
  "data": {
    "me": {
      "id": "019f0fb6-37b1-7800-b7bc-0d11288504b1",
      "workspace": {
        "id": "019f0fb6-3001-7900-b7bc-0d11288504b1",
        "workpaperTemplates": ["default", "detailed"]
      }
    }
  }
}