Skip to main content
Most queries and mutations on the GraphQL API share a common shape — the same filter operators, the same Connection wrapper around lists, the same nested-mutation conventions. This page is the reference for those shared patterns.

The Connection wrapper

Every list field in the schema (root-level lists and nested relationship lists) returns a Connection wrapper: Because the wrapper is consistent at every depth, you can pass filter, first, skip, and orderBy to a nested list the same way you pass them at the root.

Filter operators

Comparison and text

Most fields support a standard set of operators. The exact set depends on the field type — text fields get string operators, numeric fields get range operators, and so on.

Logical composition

AND, OR, and NOT compose any number of clauses. They can nest.

Date helpers

Relative date filters save you from computing exact timestamps.

Relational quantifiers

To filter parent records by the state of their related children, use some, every, and none:

Nested mutations

Every relationship field on a mutation input accepts exactly one of three operations: The whole nested mutation runs as a single transaction. If any step fails, the entire operation rolls back.
For the full mutations reference, see Mutations.

Atomic upserts

Tables with at least one unique column expose an upsert<TableName> mutation. It atomically checks the unique field and runs create or update:
Use upsert in place of “select then create or update” to eliminate the race condition.

Modifying relationships

The updateRelationship mutation changes how a foreign key behaves — cascade behavior, nullability, descriptive metadata. Names map to the underlying database constraint name.
For modeling cardinality and many-to-many patterns at the schema level, see Relationships.

Permissions and authentication

Filters, nested mutations, and upserts all run through the same authorization checks. Read access is required for filter clauses that touch a related table; write access is required for every step of a nested mutation. See Role-Based Access. Authentication tokens come from App Services → Authentication Providers.

FAQ

some is “at least one child matches” — finds parents that have any matching child. every is stricter — all children must match. Note that every also matches parents with zero children, which is sometimes surprising.
connect is the schema-level way to link by a unique field — including non-id columns like an email. Passing a raw foreign key id is shorter, but only works when you already have the id and the column is the primary key.
Faster, in practice. They run in one round-trip and one database transaction, where separate operations require a round-trip per step and don’t share a transaction. They also avoid orphaned records when a later step fails.
Yes. filter runs before grouping (SQL WHERE); having runs after (SQL HAVING). Use filter to scope the rows that participate in the aggregation, and having to drop groups whose aggregate doesn’t meet a threshold. See Queries → Grouping and aggregation.
Deep nesting works for typical use cases. For very deep filter trees, consider the _query POST endpoint on the REST API — it accepts a JSON body that’s easier to compose in code than a deeply nested GraphQL filter literal.