Skip to main content
A client is a taxpayer or return that lives inside a workspace. Every client operation is reached through the me query resolved as a WorkspaceUser, so you must authenticate with a workspaceToken (see Authentication). All requests go to:
https://router.apps.filed.com/graphql
There is no top-level clients query. Clients belong to a workspace, so you read them through me { ... on WorkspaceUser { workspace { clients(...) } } }. The workspaceToken already identifies which workspace, so you never pass a workspace ID.

The Client type

type Client {
  id: ID!
  name: String!
  externalId: String!
  status: ClientStatus!
  returnType: ReturnType!
  taxYear: Int!
  createdAt: Date!
  assignees: [WorkspaceUserShortDetails!]!
  tasks(type: TaskType, status: TaskStatus, triggeredBy: ID, limit: Int): [Task!]!
}

enum ClientStatus {
  active
  archived
}

enum ReturnType {
  F1040
  F1041
  F1065
  F1120
  F1120S
  F990
}
id
ID!
The client’s unique identifier.
name
String!
The client’s display name.
externalId
String!
Your own identifier for the client (for example the ID from your practice management system). Unique within the workspace.
status
ClientStatus!
active or archived.
returnType
ReturnType!
The tax return form: F1040, F1041, F1065, F1120, F1120S, or F990.
taxYear
Int!
The tax year, for example 2025.
createdAt
Date!
When the client was created.
assignees
[WorkspaceUserShortDetails!]!
The workspace users assigned to this client.
type WorkspaceUserShortDetails {
  id: ID!
  userId: ID!
  name: String!
  email: String
  role: WorkspaceRole!
  kind: UserKind
  createdAt: Date
  invitedByName: String
  invitedByEmail: String
}

enum WorkspaceRole {
  admin
  l1
  l2
  l3
}

enum UserKind {
  user
  backoffice_user
  assistant
  api
}
tasks
[Task!]!
Background tasks for this client (binder ingestion, tax prep, and so on). See the tasks API. Narrow with the type, status, triggeredBy, and limit arguments.
The Client type exposes more fields (binder, documents, conversations, and others) than are listed here. This page covers the fields needed to create, list, fetch, and add documents to clients.

Create a client

createClient creates a client and, optionally, kicks off binder ingestion for any documents you have already staged (see Uploading documents).
mutation CreateClient($input: CreateClientInput!) {
  createClient(input: $input) {
    client {
      id
      name
      externalId
      status
      returnType
      taxYear
    }
    taskId
  }
}

Input: CreateClientInput

input CreateClientInput {
  name: String!
  externalId: String!
  returnType: ReturnType!
  taxYear: Int!
  uploadIds: [String!]
}
name
String!
required
The client’s display name.
externalId
String!
required
Your identifier for the client. Must be unique within the workspace.
returnType
ReturnType!
required
One of F1040, F1041, F1065, F1120, F1120S, F990.
taxYear
Int!
required
The tax year, for example 2025.
uploadIds
[String!]
Optional. Upload IDs from the upload endpoint. If provided, Filed ingests these documents into the new client’s binder and returns a taskId you can track.

Returns: CreateClientResult

type CreateClientResult {
  client: Client!
  taskId: ID
}
client
Client!
The created client.
taskId
ID
The binder ingestion task ID, present only when uploadIds were supplied. null when the client was created without documents.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation CreateClient($input: CreateClientInput!) { createClient(input: $input) { client { id name externalId status returnType taxYear } taskId } }",
    "variables": {
      "input": {
        "name": "Jane Taxpayer",
        "externalId": "PMS-10432",
        "returnType": "F1040",
        "taxYear": 2025,
        "uploadIds": ["018f9c2a-7b1e-7c3d-9a4e-2f6b1c8d0e5a"]
      }
    }
  }'
{
  "data": {
    "createClient": {
      "client": {
        "id": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
        "name": "Jane Taxpayer",
        "externalId": "PMS-10432",
        "status": "active",
        "returnType": "F1040",
        "taxYear": 2025
      },
      "taskId": "018f9c2b-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
    }
  }
}

List clients

Read workspace.clients to list clients. Filter, page, and sort with the arguments below.
query ListClients($filters: ClientFilters, $offset: Int, $limit: Int, $sortBy: SortBy) {
  me {
    ... on WorkspaceUser {
      workspace {
        clients(filters: $filters, offset: $offset, limit: $limit, sortBy: $sortBy) {
          id
          name
          externalId
          status
          returnType
          taxYear
          createdAt
        }
      }
    }
  }
}

Arguments

input ClientFilters {
  ids: [ID!]
  status: [ClientStatus!]
  search: String
  assigneeIds: [ID!]
  assignedToMe: Boolean
}

input SortBy {
  field: String!
  order: SortByOrder!   # ASC | DESC
}
filters.ids
[ID!]
Return only clients with these IDs. This is how you fetch a single client.
filters.status
[ClientStatus!]
Return only clients in these statuses (active, archived).
Free-text search over client name and external ID.
filters.assigneeIds
[ID!]
Return only clients assigned to these workspace users.
filters.assignedToMe
Boolean
When true, return only clients assigned to the authenticated user.
offset
Int
Number of clients to skip, for pagination.
limit
Int
Maximum number of clients to return.
sortBy
SortBy
Sort order, for example { "field": "createdAt", "order": "DESC" }.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "query ListClients($filters: ClientFilters, $limit: Int, $sortBy: SortBy) { me { ... on WorkspaceUser { workspace { clients(filters: $filters, limit: $limit, sortBy: $sortBy) { id name externalId status returnType taxYear createdAt } } } } }",
    "variables": {
      "filters": { "status": ["active"], "search": "jane" },
      "limit": 20,
      "sortBy": { "field": "createdAt", "order": "DESC" }
    }
  }'
{
  "data": {
    "me": {
      "workspace": {
        "clients": [
          {
            "id": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
            "name": "Jane Taxpayer",
            "externalId": "PMS-10432",
            "status": "active",
            "returnType": "F1040",
            "taxYear": 2025,
            "createdAt": "2026-07-01T15:04:22.000Z"
          }
        ]
      }
    }
  }
}

Fetch a single client

There is no client(id:) query. Fetch one client by passing its ID in filters.ids and reading the first element.
query GetClient($clientId: ID!) {
  me {
    ... on WorkspaceUser {
      workspace {
        clients(filters: { ids: [$clientId] }) {
          id
          name
          externalId
          status
          returnType
          taxYear
          createdAt
          assignees {
            id
            name
            email
            role
          }
        }
      }
    }
  }
}
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "query GetClient($clientId: ID!) { me { ... on WorkspaceUser { workspace { clients(filters: { ids: [$clientId] }) { id name externalId status returnType taxYear createdAt assignees { id name email role } } } } } }",
    "variables": { "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c" }
  }'
{
  "data": {
    "me": {
      "workspace": {
        "clients": [
          {
            "id": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
            "name": "Jane Taxpayer",
            "externalId": "PMS-10432",
            "status": "active",
            "returnType": "F1040",
            "taxYear": 2025,
            "createdAt": "2026-07-01T15:04:22.000Z",
            "assignees": [
              {
                "id": "019f0fb6-37b1-7800-b7bc-0d11288504b1",
                "name": "Jane Preparer",
                "email": "jane@example-firm.com",
                "role": "admin"
              }
            ]
          }
        ]
      }
    }
  }
}
An empty clients array means no client with that ID exists in this workspace. Handle it as a not-found result.

Add documents to a client

addClientDocuments attaches already-staged uploads to an existing client and ingests them into the client’s binder. Stage the files first with the upload endpoint.
mutation AddClientDocuments($input: AddClientDocumentsInput!) {
  addClientDocuments(input: $input) {
    taskId
  }
}

Input: AddClientDocumentsInput

input AddClientDocumentsInput {
  clientId: ID!
  uploadIds: [String!]!
}
clientId
ID!
required
The client to add documents to.
uploadIds
[String!]!
required
One or more upload IDs from the upload endpoint.

Returns: AddClientDocumentsResult

type AddClientDocumentsResult {
  taskId: ID
}
taskId
ID
The binder ingestion task ID. Poll it until status is COMPLETED to know the documents are filed in the binder.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation AddClientDocuments($input: AddClientDocumentsInput!) { addClientDocuments(input: $input) { taskId } }",
    "variables": {
      "input": {
        "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
        "uploadIds": ["018f9c2a-7b1e-7c3d-9a4e-2f6b1c8d0e5a"]
      }
    }
  }'
{
    "data": {
    "addClientDocuments": {
      "taskId": "018f9c2b-1a2b-7c3d-8e4f-5a6b7c8d9e0f"
    }
  }
}

Manage clients

Beyond create, list, and fetch, the API exposes a set of mutations for the rest of the client lifecycle: rename, archive, restore, permanently delete, and assign or unassign workspace users. All of them take a single input argument identified by clientId, return either the updated Client or a Boolean, and require a workspaceToken (see Authentication).

Update a client

updateClient renames a client. Only the name is mutable through this mutation.
mutation UpdateClient($input: UpdateClientInput!) {
  updateClient(input: $input) {
    id
    name
    externalId
    status
    returnType
    taxYear
  }
}

Input: UpdateClientInput

input UpdateClientInput {
  clientId: ID!
  name: String!
}
clientId
ID!
required
The ID of the client to rename.
name
String!
required
The new display name for the client.

Returns: Client!

The updated Client.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation UpdateClient($input: UpdateClientInput!) { updateClient(input: $input) { id name externalId status returnType taxYear } }",
    "variables": {
      "input": {
        "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
        "name": "Jane Q. Taxpayer"
      }
    }
  }'
{
  "data": {
    "updateClient": {
      "id": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
      "name": "Jane Q. Taxpayer",
      "externalId": "PMS-10432",
      "status": "active",
      "returnType": "F1040",
      "taxYear": 2025
    }
  }
}

Archive a client

archiveClient sets the client’s status to archived. Archived clients are excluded from default lists but kept on disk and can be restored.
mutation ArchiveClient($input: ArchiveClientInput!) {
  archiveClient(input: $input) {
    id
    name
    status
  }
}

Input: ArchiveClientInput

input ArchiveClientInput {
  clientId: ID!
}
clientId
ID!
required
The ID of the client to archive.

Returns: Client!

The archived Client with status set to archived.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation ArchiveClient($input: ArchiveClientInput!) { archiveClient(input: $input) { id name status } }",
    "variables": {
      "input": { "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c" }
    }
  }'
{
  "data": {
    "archiveClient": {
      "id": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
      "name": "Jane Q. Taxpayer",
      "status": "archived"
    }
  }
}

Restore a client

restoreClient sets an archived client’s status back to active.
mutation RestoreClient($input: RestoreClientInput!) {
  restoreClient(input: $input) {
    id
    name
    status
  }
}

Input: RestoreClientInput

input RestoreClientInput {
  clientId: ID!
}
clientId
ID!
required
The ID of the archived client to restore.

Returns: Client!

The restored Client with status set to active.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation RestoreClient($input: RestoreClientInput!) { restoreClient(input: $input) { id name status } }",
    "variables": {
      "input": { "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c" }
    }
  }'
{
  "data": {
    "restoreClient": {
      "id": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
      "name": "Jane Q. Taxpayer",
      "status": "active"
    }
  }
}

Delete a client

deleteClient permanently removes a client and its binder. It cannot be undone.
deleteClient is irreversible. The client, its documents, and its binder are permanently removed. Prefer archiveClient when you only need to hide a client from active lists.
mutation DeleteClient($input: DeleteClientInput!) {
  deleteClient(input: $input)
}

Input: DeleteClientInput

input DeleteClientInput {
  clientId: ID!
}
clientId
ID!
required
The ID of the client to permanently delete.

Returns: Boolean!

true when the client was deleted.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation DeleteClient($input: DeleteClientInput!) { deleteClient(input: $input) }",
    "variables": {
      "input": { "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c" }
    }
  }'
{
  "data": {
    "deleteClient": true
  }
}

Assign a user to a client

assignUserToClient assigns a workspace user to a client and returns the created ClientAssignee.
mutation AssignUserToClient($input: AssignUserToClientInput!) {
  assignUserToClient(input: $input) {
    id
    clientId
    user {
      id
      userId
      name
      email
      role
    }
    assignedBy {
      id
      userId
      name
      email
      role
    }
    createdAt
  }
}

Input: AssignUserToClientInput

input AssignUserToClientInput {
  clientId: ID!
  userId: ID!
}
clientId
ID!
required
The ID of the client to assign the user to.
userId
ID!
required
The ID of the workspace user to assign. Use the userId of a WorkspaceUserShortDetails from the workspace’s members, or the id returned by me.

Returns: ClientAssignee!

type ClientAssignee {
  id: ID!
  clientId: ID!
  user: WorkspaceUserShortDetails!
  assignedBy: WorkspaceUserShortDetails!
  createdAt: Date!
}
id
ID!
The assignment record ID.
clientId
ID!
The client the user was assigned to.
user
WorkspaceUserShortDetails!
The workspace user who was assigned. See WorkspaceUserShortDetails under assignees for the field shape.
assignedBy
WorkspaceUserShortDetails!
The workspace user who performed the assignment (the authenticated caller).
createdAt
Date!
When the assignment was created.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation AssignUserToClient($input: AssignUserToClientInput!) { assignUserToClient(input: $input) { id clientId user { id userId name email role } assignedBy { id userId name email role } createdAt } }",
    "variables": {
      "input": {
        "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
        "userId": "019f0fb6-37b1-7800-b7bc-0d11288504b1"
      }
    }
  }'
{
  "data": {
    "assignUserToClient": {
      "id": "019f0fb6-4a2c-7900-9c01-2b3c4d5e6f70",
      "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
      "user": {
        "id": "019f0fb6-37b1-7800-b7bc-0d11288504b1",
        "userId": "019f0fb6-3001-7900-b7bc-0d11288504b1",
        "name": "Jane Preparer",
        "email": "jane@example-firm.com",
        "role": "admin"
      },
      "assignedBy": {
        "id": "019f0fb6-37b1-7800-b7bc-0d11288504b1",
        "userId": "019f0fb6-3001-7900-b7bc-0d11288504b1",
        "name": "Jane Preparer",
        "email": "jane@example-firm.com",
        "role": "admin"
      },
      "createdAt": "2026-07-04T18:22:01.000Z"
    }
  }
}

Unassign a user from a client

unassignUserFromClient removes a workspace user’s assignment from a client.
mutation UnassignUserFromClient($input: UnassignUserFromClientInput!) {
  unassignUserFromClient(input: $input)
}

Input: UnassignUserFromClientInput

input UnassignUserFromClientInput {
  clientId: ID!
  userId: ID!
}
clientId
ID!
required
The ID of the client to remove the assignment from.
userId
ID!
required
The ID of the workspace user to unassign.

Returns: Boolean!

true when the assignment was removed.
curl -X POST https://router.apps.filed.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_WORKSPACE_TOKEN" \
  -d '{
    "query": "mutation UnassignUserFromClient($input: UnassignUserFromClientInput!) { unassignUserFromClient(input: $input) }",
    "variables": {
      "input": {
        "clientId": "018f9c2a-3d5f-7a10-b2c4-9e8d7f6a5b4c",
        "userId": "019f0fb6-37b1-7800-b7bc-0d11288504b1"
      }
    }
  }'
{
  "data": {
    "unassignUserFromClient": true
  }
}