Skip to main content
Filed sends workspace-scoped task status events to HTTPS endpoints you configure. Use webhooks when your integration needs task updates without polling the tasks API. This guide includes every argument, input field, return field, and default value for the webhook GraphQL operations it documents because schema introspection is not available.

Before you begin

All GraphQL requests use:
The event catalog is public. Listing or managing webhook endpoints requires an administrator’s read-write workspaceToken. Send the token as a bearer token:
See Authentication for token setup.

Complete GraphQL schema

The following is the complete schema available for webhook configuration. No other arguments or fields are required to use this API.

1. Discover supported events

Query the catalog instead of hard-coding event support. This query has no arguments or variables and does not require a workspace ID.
payloadSchema contains the complete Draft 7 JSON Schema for that event, not only the abbreviated fields shown above. The current event catalog is: task.* reports the task as a whole. subtask.* reports each stage inside it — extraction, reconciliation, data entry and the rest. A stage is only reported when it finishes, so these mark completion rather than progress. AI_DATA_ENTRY is the data entry a preparer starts and reviews in Filed, so its events follow what the preparer does rather than a single run. task.running arrives when they start data entry for the client, task.completed each time entries are sent to the tax software and verified, and task.failed when a preparation or a send fails. A preparer can prepare and send again after new documents arrive, so one task can complete more than once. These events carry no taxPrepResult. task.paused fills the gap between those. Tasks pause for many reasons, and most are not worth an event, so Filed emits it only with a reason it publishes. The first is ready_for_review: a data entry preparation finished and its entries are waiting for a person to review them and send them to the tax software. actionUrl opens them in Filed. A preparation that fails emits task.failed instead. The second is needs_tax_software_client: data entry was requested for a client Filed could not find in the firm’s tax software, by the ID sent or by name, and actionUrl opens the page where a person picks the client. task.files_ready carries download links to what a task produced. Files arrive as separate events, each when its file is ready, so expect more than one per task. Every event also carries binderUrl, a link that opens the client’s binder in Filed. For AI_DATA_ENTRY, up to three events each time entries are sent:
  1. The tax software’s backup (software_backup), right after the entries are sent and verified. Drake, Lacerte and UltraTax only.
  2. The finished binder (binder), a few seconds after task.completed. Only for a client your integration sent.
  3. The printed return (tax_return), a few minutes after task.completed, and only when the tax software can print.
For TAX_PREP, up to two events:
  1. The return, workpaper, input screens and CCH backup the run produced (tax_return, tax_workpaper, input_screens, software_backup), together, alongside task.completed.
  2. The finished binder (binder), a few seconds later. Only for a client your integration sent.
Keep the files by kind: a later file of the same kind replaces the earlier one, for example when a return is printed again. A task that produced nothing to download sends no event. documents.synced is not a task event, which is why it carries no status or task type. Filed emits it when documents are pulled into a client from a connected system — a document management system, or a practice management system such as Canopy, Karbon or Truss. It arrives before any processing begins, so it tells you documents landed, not what Filed made of them. Its payload names the connectionId and providerKey they came from, the sourceExternalId of the folder or project, and each document’s inputDocumentId, fileName and mimeType. duplicateCount reports how many files in the same pull Filed already held and therefore left out. Documents added by hand rather than pulled from a connection do not raise it. Subscribe to subtask.* only if you need stage detail. A single tax prep moves through many stages, so these are an order of magnitude more traffic than task.*. eventTypes on an endpoint is how you choose: subscribe to task.* alone and you never receive them. An endpoint created without eventTypes receives every event, current and future — so an endpoint made before subtask.* existed now receives it too. Set eventTypes explicitly on those endpoints to keep the volume you had.

2. Create an endpoint

Create an endpoint once for each delivery destination. New endpoints are enabled by default.
Variables using every available input field:
Store signingSecret immediately in a secrets manager. Filed returns it only when the endpoint is created or its secret is rotated. Do not put it in source control or expose it to browser code.

Complete cURL request

3. List endpoints

Endpoint listing is cursor-paginated and is reached through the authenticated workspace returned by me.
All query arguments:
All page and endpoint return fields: To read every endpoint, send the returned iterator in the next request until done is true.

4. Update an endpoint

The update mutation is a patch: provide endpointId and only the fields you want to change. At least one update field must be present.
Variables using every available input field:
GraphQL distinguishes an omitted input field from an explicitly supplied null. This matters for description and eventTypes, where null clears or resets the existing value.
Pause an endpoint without deleting it:

5. Rotate a signing secret

Rotate a secret before you suspect compromise or as part of regular credential hygiene.
The response contains every WebhookEndpoint field plus the new signingSecret. Deploy the new secret before the grace period ends, verify a delivery with it, and then remove the old secret.

6. Delete an endpoint

Deletion stops delivery permanently for that endpoint.
Use enabled: false with updateWebhookEndpoint instead when you may need to resume the endpoint later.

7. Receive the payload

Every event uses the same version 2 envelope:

Sub-task payload

subtask.* uses the same envelope, minus taxPrepResult and customerError, plus the stage it reports:

Paused payload

Files ready payload

Treat url as a secret: anyone holding it can download the file until it expires. Download the file when the event arrives and store it on your side rather than keeping the link. Each request also includes these Svix signature headers:

8. Verify the signature

Verify the raw request body before parsing JSON or changing application state.
Do not verify a parsed or re-serialized JSON object. Whitespace or key ordering changes invalidate the signature. Pass the exact raw request body to the Svix verification library.

9. Handle duplicates, ordering, and retries

Webhook delivery is at least once. Store the webhook-id in a table with a uniqueness constraint before applying the event. If the ID has already been handled, return a successful response without applying it again. Events can be delayed or arrive out of order. Compare occurredAt with the latest status transition you have stored, and do not let an older event replace newer state. Return a 2xx response promptly after durable acceptance. Move slow work to a queue. Non-2xx responses and network failures are retried.
Treat webhook events as notifications, not as the only task record. To reconcile state, query the task by taskId through the tasks API.

Common GraphQL errors