Skip to main content
Tax prep extracts forms from a client’s binder, reconciles them, optionally enters them into tax software, and produces a list of review items. It runs as a background task, so the end-to-end sequence is: start the run, poll the task until it finishes, then read the result. This recipe is the minimal call sequence to do that for one client. Every call uses a workspaceToken (see Authentication) and goes to the single GraphQL endpoint:
https://router.apps.filed.com/graphql
This recipe does not re-document the types it touches. For the full input shape, the backoffice re-trigger/status operations, and the complete TaskTaxPrepResult field list, see Tax prep. For the polling mechanics, see Tasks.

1. Start the run

Start a tax prep run with triggerTaxPrep. The only required fields are the client’s clientId and the returnType you want to prepare (it must match the client’s returnType, see Clients). The mutation returns a taskId you poll in the next step.
mutation TriggerTaxPrep($input: TriggerTaxPrepInput!) {
  triggerTaxPrep(input: $input) {
    taskId
  }
}
{
  "input": {
    "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
    "returnType": "F1040"
  }
}
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation TriggerTaxPrep($input: TriggerTaxPrepInput!) { triggerTaxPrep(input: $input) { taskId } }",
    "variables": {
      "input": {
        "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
        "returnType": "F1040"
      }
    }
  }'
{
  "data": {
    "triggerTaxPrep": {
      "taskId": "018f9c2b-7c4d-7e10-9a22-6b3c4d5e6f70"
    }
  }
}
Save the taskId. You will use it to find the task in the poll step.
To scope which workspace and user skills apply to this run, pass skills: { workspace: [...], user: [...] } (RunSkillSelectionInput). Omit it to apply all active skills. See Tax prep, start a run for the full input.

2. Poll the task to completion

There is no task(id:) query. Poll the task you just started by listing the client’s TAX_PREP tasks and reading the entry whose id matches the taskId returned above. The polling mechanics are documented on Tasks; the short version:
query PollTaxPrep($clientId: ID!) {
  me {
    ... on WorkspaceUser {
      workspace {
        clients(filters: { ids: [$clientId] }) {
          tasks(type: TAX_PREP, limit: 1) {
            id
            status
            startedAt
            completedAt
            errorMessage
            subTasks {
              type
              status
            }
          }
        }
      }
    }
  }
}
{
  "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c"
}
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "query PollTaxPrep($clientId: ID!) { me { ... on WorkspaceUser { workspace { clients(filters: { ids: [$clientId] }) { tasks(type: TAX_PREP, limit: 1) { id status startedAt completedAt errorMessage subTasks { type status } } } } } } }",
    "variables": { "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c" }
  }'
{
  "data": {
    "me": {
      "workspace": {
        "clients": [
          {
            "tasks": [
              {
                "id": "018f9c2b-7c4d-7e10-9a22-6b3c4d5e6f70",
                "status": "RUNNING",
                "startedAt": "2026-07-04T10:02:00.000Z",
                "completedAt": null,
                "errorMessage": null,
                "subTasks": [
                  { "type": "EXTRACT", "status": "COMPLETED" },
                  { "type": "RECONCILE", "status": "RUNNING" }
                ]
              }
            ]
          }
        ]
      }
    }
  }
}
Poll on an interval (for example every few seconds) until status is no longer RUNNING. COMPLETED means the run succeeded and result is now selectable as TaskTaxPrepResult; FAILED means it did not, and errorMessage (plus subTasks[].errorMessage) explains which stage failed.

3. Read the completed result

When the task is COMPLETED, select result with an inline fragment on TaskTaxPrepResult to read the summary, counts, and review items. Always read __typename on result and include a ... on TaskUnknownResult fallback: a TAX_PREP task that fails after the run starts can resolve to TaskUnknownResult instead of TaskTaxPrepResult, and branching on __typename keeps your client from throwing on the unexpected member.
query TaxPrepResult($clientId: ID!) {
  me {
    ... on WorkspaceUser {
      workspace {
        clients(filters: { ids: [$clientId] }) {
          tasks(type: TAX_PREP, limit: 1) {
            id
            status
            completedAt
            result {
              __typename
              ... on TaskTaxPrepResult {
                taxYear
                returnType
                summary
                documentCount
                extractedFormCount
                reviewItemCount
                reviewItems {
                  severity
                  category
                  description
                }
              }
              ... on TaskUnknownResult {
                message
              }
            }
          }
        }
      }
    }
  }
}
{
  "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c"
}
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "query TaxPrepResult($clientId: ID!) { me { ... on WorkspaceUser { workspace { clients(filters: { ids: [$clientId] }) { tasks(type: TAX_PREP, limit: 1) { id status completedAt result { __typename ... on TaskTaxPrepResult { taxYear returnType summary documentCount extractedFormCount reviewItemCount reviewItems { severity category description } } ... on TaskUnknownResult { message } } } } } } } }",
    "variables": { "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c" }
  }'
{
  "data": {
    "me": {
      "workspace": {
        "clients": [
          {
            "tasks": [
              {
                "id": "018f9c2b-7c4d-7e10-9a22-6b3c4d5e6f70",
                "status": "COMPLETED",
                "completedAt": "2026-07-04T10:11:48.000Z",
                "result": {
                  "__typename": "TaskTaxPrepResult",
                  "taxYear": 2025,
                  "returnType": "F1040",
                  "summary": "Return prepared from 14 documents with 9 extracted forms. 3 items need review before sign-off.",
                  "documentCount": 14,
                  "extractedFormCount": 9,
                  "reviewItemCount": 3,
                  "reviewItems": [
                    {
                      "severity": "high",
                      "category": "missing_form",
                      "description": "W-2 from Acme Corp referenced in prior year but not present in this year's binder."
                    },
                    {
                      "severity": "medium",
                      "category": "value_mismatch",
                      "description": "Schedule B interest total differs from 1099-INT sum by $42."
                    },
                    {
                      "severity": "low",
                      "category": "data_entry",
                      "description": "Filing status set to Married Filing Jointly; confirm against intake form."
                    }
                  ]
                }
              }
            ]
          }
        ]
      }
    }
  }
}

4. Use the review items

Two reads cover most needs:
  • Quick check: read reviewItemCount for a single “how much needs attention” number before paging through the items.
  • Per-item detail: read reviewItems, each with severity, category, and description. severity is a free-form String! (not an enum), so sort and group it in your client as you see fit.
TaskTaxPrepResult is one member of the TaskResult union. The other tax members are TaskTaxReviewResult (returned for TAX_REVIEW tasks) and TaskTaxAdvisorResult (returned for TAX_ADVISOR tasks). See Tasks, task result for the full union and the inline-fragment pattern used to select it.

Next steps

Once review items exist, the natural next step is to work through them and record sign-offs on the sheets and rows that produced each item. See Review and sign off for that recipe.