api
Querying your data with GraphQL
The schema is composed per tenant from your installed modules. Each module exposes list and get queries plus create/update/transition mutations, all over a consistent record shape.
7 min read · 5 sections
Endpoint & scope
- Single endpoint: POST https://app.qehsethos.com/api/graphql.
- Your schema contains your installed modules plus the account queries — not modules you have not installed.
- Send the active workspace with an `x-qehs-tenant: <tenantId>` header. Browser session requests default to your active membership; multi-workspace and owner callers should set it explicitly.
Account queries (always available)
query {
me { id email name isSuperAdmin }
myTenants { tenantName role }
activeTenant { role tenant { name plan status } }
}Module queries
Every installed module gets two queries named after its key: `<module>List` and `<module>Get`. The name is the module’s key in camelCase, so a module installed as `action_items_acme` becomes `actionItemsAcmeList` / `actionItemsAcmeGet`. The console’s preset cards and the IDE explorer show the exact names for your modules.
query {
# Latest 10 records, newest first
actionItemsAcmeList(limit: 10, offset: 0) {
id
displayCode
workflowState
createdAt
data # the full record payload (JSON)
}
}The record shape
Every module record exposes the same fields. The configurable, per-module fields live inside `data` (a JSON object keyed by your Composer field keys); the rest are platform metadata.
| Field | Type | Meaning |
|---|---|---|
| id | ID! | Record UUID |
| displayCode | String | Human-readable code (e.g. ACT-2026-0001) |
| workflowState | String | Current workflow state key |
| data | JSON! | Your Composer field values, keyed by field key |
| createdAt / updatedAt | DateTime! | Timestamps (UTC) |
| definitionVersion | Int! | Module definition version the record was written against |
Mutations
Each module also exposes `<module>Create(data)`, `<module>Update(id, data)`, and `<module>Transition(id, nextState)`. Writes validate against the module definition and run through the same workflow state machine and audit trail as the UI.
mutation {
actionItemsAcmeCreate(data: { title: "Replace guard rail", priority: "high" }) {
id
displayCode
workflowState
}
}