Skip to main content
Condo exposes a complete GraphQL API built on KeystoneJS 5. Every domain model — tickets, properties, residents, billing, organizations — is available as a GraphQL type with a consistent set of queries, mutations, and filtering capabilities.

API endpoint

The GraphQL endpoint is available at:
POST /api/graphql
For the main condo application the default port in local development is 4006, so the full URL is:
http://localhost:4006/api/graphql
All requests must be POST with a JSON body containing a query (or mutation) string and optional variables object. Authenticated requests carry a session cookie obtained from one of the sign-in mutations.

GraphQL Playground

Keystone ships with a built-in GraphQL Playground (GraphiQL) at the same path when the NODE_ENV is not production:
http://localhost:4006/api/graphql
You can use introspection queries or the Playground UI to browse the full schema, including auto-generated documentation for every field.

API capabilities

Queries

List and filter records with allModels(where: ..., first: ..., skip: ...), retrieve counts with _allModelsMeta, and fetch single items by ID.

Mutations

Create, update, and batch-create/update records. Soft deletes are performed by setting deletedAt. Hard deletes are disabled for most models.

Custom mutations

Domain-specific operations such as authenticateUserWithEmailAndPassword, registerNewServiceUser, startConfirmPhoneAction, and more.

Schema introspection

Full introspection support. Use the __schema and __type queries to programmatically discover types, fields, and input shapes.

Key entity types

TypeDescription
OrganizationProperty management company. All data is scoped to an organization.
PropertyA managed building or residential complex.
TicketA maintenance or service request raised by a resident or staff.
ContactA resident or contact associated with a property.
BillingReceiptA billing document sent to a resident.
UserA platform user (staff, resident, or service account).
OrganizationEmployeeLinks a User to an Organization with a specific role.
B2BAppA mini-app integrated into the Condo marketplace.

Query patterns

All list queries follow a consistent shape:
query GetTickets {
  allTickets(
    where: { organization: { id: "<org-id>" }, status: { name: "open" } }
    sortBy: [createdAt_DESC]
    first: 20
    skip: 0
  ) {
    id
    number
    details
    status {
      name
    }
    property {
      address
    }
    createdAt
    updatedAt
  }
}
To get a total count without fetching all rows:
query CountTickets {
  _allTicketsMeta(
    where: { organization: { id: "<org-id>" } }
  ) {
    count
  }
}

Mutation patterns

Create and update mutations accept an input or data object. The dv (data version) and sender fields are required on all mutations that modify data:
mutation CreateTicket {
  createTicket(data: {
    dv: 1
    sender: { dv: 1, fingerprint: "my-integration" }
    organization: { connect: { id: "<org-id>" } }
    property: { connect: { id: "<property-id>" } }
    details: "Water leak in apartment 42"
    source: { connect: { id: "<source-id>" } }
    classifier: { connect: { id: "<classifier-id>" } }
  }) {
    id
    number
    details
  }
}

Filtering

Every model exposes a WhereInput type with operators for each field:
Operator suffixMeaning
(none)Exact match
_notNot equal
_containsSubstring match (case-sensitive)
_contains_iSubstring match (case-insensitive)
_starts_withPrefix match
_inValue is in list
_not_inValue is not in list
_gt, _lt, _gte, _lteNumeric / date comparisons
Filters can be combined with AND and OR:
where: {
  AND: [
    { organization: { id: "<org-id>" } }
    { createdAt_gte: "2024-01-01T00:00:00Z" }
  ]
}

Access control

All data in Condo is organization-scoped. The rules enforced by the API:
  • Organization membership — users can only read and write data that belongs to organizations they are employees of.
  • Role-based permissions — the OrganizationEmployee role determines which mutations and fields a user can access within an organization.
  • Service users — programmatic integrations use a SERVICE-type user account that can be granted elevated rights via UserRightsSet.
  • Soft deletes — records are never physically removed by default; they are marked with a deletedAt timestamp and excluded from list query results automatically.
Apollo Client is the recommended library for consuming the Condo GraphQL API. The @open-condo/apollo package (used internally throughout the monorepo) provides pre-configured Apollo instances with session cookie handling.
yarn add @apollo/client graphql
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'

const client = new ApolloClient({
  link: createHttpLink({
    uri: 'http://localhost:4006/api/graphql',
    credentials: 'include', // send session cookie
  }),
  cache: new InMemoryCache(),
})

Build docs developers (and LLMs) love