Filtering & conditions
Most collection-returning queries in the Accord API are Relay-style
connections. A connection takes pagination arguments and returns a list
of edges plus page info, and supports two kinds of filtering: exact-
match condition and operator-based filter.
Connection fields are named …Connection — accordsConnection,
workspaceAccountsConnection, resourcesConnection. Reach for these
by default; they're the only fields that support cursor pagination.
Pagination
Connections accept the standard Relay pagination arguments:
| Argument | Purpose |
|---|---|
first: Int | Take the first N results. |
after: Cursor | Start the page after the given cursor. |
last: Int | Take the last N results. |
before: Cursor | End the page before the given cursor. |
offset: Int | Skip the first N results (offset paging). |
Each page returns edges { cursor node { … } } and a pageInfo block:
query FirstPage {
accordsConnection(first: 25) {
edges {
cursor
node {
id
opportunityName
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
To fetch the next page, pass endCursor back as after:
query NextPage($cursor: Cursor!) {
accordsConnection(first: 25, after: $cursor) {
edges { node { id opportunityName } }
pageInfo { hasNextPage endCursor }
}
}
If you don't need cursors, every connection also exposes a flat
nodes list that skips the edges/node wrapping:
query FlatPage {
accordsConnection(first: 25) {
nodes { id opportunityName }
}
}
totalCount is not freeConnections expose totalCount, but the database runs it as a separate
count over the whole filtered set, on top of the query for the page
itself. On large collections that roughly doubles the cost of the
request. Skip it unless you genuinely need an exact total — to drive a
"load more" affordance, read pageInfo.hasNextPage instead.
The non-connection shortcut
Alongside each connection there's a plain list field with the same
filtering vocabulary — accords, workspaceAccounts — that returns
[Accord!]! directly:
query FewAccords {
accords(first: 10, filter: { isTemplate: { equalTo: false } }) {
id
opportunityName
}
}
It's convenient for a small, bounded fetch, but it takes only first,
offset, orderBy, condition, and filter — there's no after,
before, last, pageInfo, or totalCount. Anything that needs to
page through a full collection should use the connection.
Ordering
Connections accept an orderBy argument typed as a collection-specific
enum. Each ordering key has _ASC and _DESC variants:
query Recent {
accordsConnection(first: 10, orderBy: CREATED_AT_DESC) {
edges {
node {
id
opportunityName
createdAt
}
}
}
}
Order by multiple keys by passing an array:
query Sorted {
accordsConnection(first: 10, orderBy: [STATUS_ASC, CREATED_AT_DESC]) {
edges { node { id opportunityName } }
}
}
See each collection's …OrderBy enum in the API reference
for the available keys.
Filtering: condition
The simplest filter is condition, an exact-match object whose fields
are the columns you want to constrain. Every field is AND-ed together.
query LiveAccords {
accordsConnection(condition: { isTemplate: false }) {
edges { node { id opportunityName } }
}
}
Use condition when you want plain equality on one or more fields.
condition covers stored columns only. Computed fields — status,
overallStatus, customerHealth, firstIncompleteStepOwner and the
rest — appear in filter but not in condition. If a field you expect
is missing from a …Condition input, use filter instead.
Filtering: filter
For richer matching (comparisons, IN, LIKE, null checks, boolean
logic), use filter. Each scalar field exposes an operator object:
query SlippingNamed {
accordsConnection(
filter: {
status: { in: ["AT_RISK", "STALLED"] }
opportunityName: { likeInsensitive: "%onboarding%" }
archivedAt: { isNull: true }
}
) {
edges { node { id opportunityName status } }
}
}
status is a String, not an enum, so its values are quoted. An
Accord's status is one of NOT_STARTED, ON_TRACK, AT_RISK,
STALLED, or COMPLETED.
Operators by type
| Type | Common operators |
|---|---|
| All scalars | equalTo, notEqualTo, in, notIn, isNull |
| Strings | like, notLike, likeInsensitive, includes, startsWith, endsWith |
| Numbers, dates, UUIDs | greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo |
| Lists / arrays | contains, containedBy, overlaps |
The exact operator set for a given field is documented under each
…Filter input type in the API reference.
Logical operators
filter accepts and, or, and not for combining conditions:
query CombinedFilter {
accordsConnection(
filter: {
or: [
{ opportunityName: { likeInsensitive: "%alpha%" } }
{ accountName: { likeInsensitive: "%beta%" } }
]
and: [{ status: { notEqualTo: "COMPLETED" } }]
}
) {
edges { node { id opportunityName accountName } }
}
}
Combining everything
first/after, orderBy, condition, and filter all compose:
query Search($cursor: Cursor) {
accordsConnection(
first: 50
after: $cursor
orderBy: CREATED_AT_DESC
condition: { createdById: "USER_UUID" }
filter: { opportunityName: { likeInsensitive: "%Q3%" } }
) {
edges {
cursor
node {
id
opportunityName
createdAt
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
Filtering and ordering both run on the database. Prefer narrower filters
and reasonable page sizes (first: 25–100) over fetching everything
and filtering client-side.