Skip to main content
The Filed API uses a small set of conventions that apply to every operation: custom GraphQL scalars, opaque identifiers, offset-based pagination, a shared sort input, and typed filter inputs. This page is the single reference for those conventions so callers and AI agents do not have to infer them. For the full type detail of a specific operation, see Clients and Tasks. All requests go to:
https://router.apps.filed.com/graphql

Scalars

The schema builds on the standard GraphQL scalars and adds two custom ones. Both are declared at the top of the platform schema:
scalar Date
scalar JSON

ID

The ID scalar is the type used for every identifiable object: clients, tasks, workspace users, uploads, and so on. Treat it as an opaque string. Always send it back exactly as you received it; never parse it, slice it, or assume a specific length. The two concrete scalar declarations in the live schema are ID (the built-in) and the custom Date and JSON below.
Filed ID values are UUIDv7 strings, for example 019f0fb6-37b1-7800-b7bc-0d11288504b1. You can confirm this from any example response in these docs: the first three segments encode a Unix timestamp (milliseconds) so IDs are roughly time-ordered, followed by random bits. This is an implementation detail you can rely on for ordering and debugging, but you should still round-trip the value as an opaque string and not construct IDs yourself.

Date

The Date scalar is an ISO 8601 timestamp string (RFC 3339), for example 2025-07-04T17:21:43.123Z. Every timestamp field in the schema (createdAt, startedAt, completedAt, etc.) uses this scalar, even when the field name does not contain the word Date. startedAt and completedAt on Task are non-null String rather than the Date scalar, but they carry the same ISO 8601 string format.

JSON

The JSON scalar holds an arbitrary JSON value: an object, array, string, number, boolean, or null. It is used wherever a field’s value is structured but not fixed by the schema, for example AI task results. The TaskTaxAdvisorResult.byDomain field is a non-null JSON scalar that returns a structured object whose shape is defined by the tax advisor task, not by the GraphQL type system.
type TaskTaxAdvisorResult {
  taxYear: Int!
  returnType: ReturnType!
  summary: String!
  strategyTotal: Int!
  byDomain: JSON!
  bySavingsHorizon: JSON!
  estimatedSavingsCentsByHorizon: JSON!
}
When you select a JSON field, you get the whole value back as-is. There is no sub-selection, so for deeply structured results you parse the JSON on the client. Keep your client’s parser lenient: the object’s keys can grow over time.

Pagination

List fields use offset-based pagination with two optional integer arguments, offset and limit. Both are plain Int scalars (nullable, so you can omit either).
  • offset is the number of items to skip before the first returned item. It is zero-based, so offset: 0 (or omitting it) returns from the start.
  • limit is the maximum number of items to return in a single response.
  • The list is always a non-null list of non-null items, for example [Client!]! or [Task!]!. An empty page is an empty array, never null.
The Filed API does not currently expose a cursor-based Connection type or a totalCount field. Page through a list by walking offset forward in steps of limit until the returned list is shorter than limit (or empty). The Workspace.tasks and Workspace.clients fields both follow this shape.

Example: page through clients

query ListClients($offset: Int, $limit: Int) {
  me {
    ... on WorkspaceUser {
      workspace {
        clients(offset: $offset, limit: $limit) {
          id
          name
        }
      }
    }
  }
}
{
  "offset": 0,
  "limit": 25
}
Send the next request with "offset": 25 and the same limit to fetch the next page. Stop when fewer than limit items come back. See Clients for the full Client type and the filters/sortBy arguments.

Sorting

List fields that accept sortBy use the shared SortBy input type. It is a single optional argument applied to the list before pagination.
input SortBy {
  field: String!
  order: SortByOrder!
}

enum SortByOrder {
  ASC
  DESC
}
field is the name of the field to sort by, as a string (for example "createdAt", "name", "startedAt"). order is ASC for ascending or DESC for descending. Both field and order are non-null inside SortBy, so if you pass a sortBy value at all you must supply both. Omit the whole sortBy argument to use the API’s default order.
{
  "sortBy": { "field": "createdAt", "order": "DESC" }
}
The same SortBy input is reused by every list field that supports sorting: Workspace.clients, Workspace.tasks, and Workspace.workspaceUsers.

Filtering

List fields take a typed filter input named after the entity: ClientFilters for clients, TaskFilters for tasks. Each input is a nullable argument, so you can omit it entirely or pass only the keys you care about. Every key inside the input is itself optional, and combining keys applies them as a logical AND.

ClientFilters

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

enum ClientStatus {
  active
  archived
}
Use ids to fetch a known set of clients by ID (passing a single-element list is how you fetch one client). Use status to filter by lifecycle state, search for free-text search over client name and external ID, and assigneeIds or assignedToMe to filter by assignee. Full field detail is on the Clients page.

TaskFilters

input TaskFilters {
  type: TaskType
  status: TaskStatus
  triggeredBy: ID
  search: String
}
Filter tasks by type (for example BINDER to follow a binder job), by status (RUNNING, COMPLETED, FAILED), by the user who started the task with triggeredBy, or with free-text search. Full field detail is on the Tasks page.
Client.tasks(type:, status:, triggeredBy:, limit:) takes the same filtering concepts as inline scalar arguments (not a TaskFilters input) and does not take offset or sortBy. Use it when you want the tasks for one client; use Workspace.tasks(filters:, sortBy:, limit:, offset:) when you want tasks across the whole workspace.

Next steps