Reference

ObjectQL

The structured query format behind the data API, views, reports and AI tools — where ObjectOS uses it, a few examples, and the full syntax on objectstack.ai.

Full specification: ObjectQL query syntax on objectstack.ai. This page is the summary: where ObjectOS uses it, and a few examples.

ObjectQL is the JSON query format the data engine consumes. A query names an object and says which records to return: a where filter, an orderBy, a page (limit, offset), the relations to expand, and optionally a groupBy with aggregations. Every query runs as the user who asked it, so it only ever returns records and fields that user may read.

Where ObjectOS uses it

  • The data API — GET /api/v1/data/:object takes a query as query-string parameters; POST /api/v1/data/:object/query takes the full body, and is the one that accepts groupBy and aggregations (REST API).
  • Views — a view's filter and sort compile to ObjectQL (Views).
  • Reports — a report serialises to ObjectQL.
  • AI — the query_data tool produces an ObjectQL body.

Examples

Open tickets that are urgent or overdue. Field operators start with $; $and, $or and $not combine them, and { "$cel": "…" } embeds a CEL expression the server evaluates at query time:

{
  "$and": [
    { "status": { "$eq": "open" } },
    {
      "$or": [
        { "priority": { "$in": ["high", "urgent"] } },
        { "due_at":   { "$lt": { "$cel": "now()" } } }
      ]
    }
  ]
}

Tickets with their assignee and customer account, resolved in one batch instead of one request per row:

{
  "object": "support_ticket",
  "expand": ["assignee", "customer.account"],
  "limit": 20
}

Monthly sales per customer, over 10,000, with POST /data/order/query:

{
  "object": "order",
  "where": { "status": { "$ne": "cancelled" } },
  "groupBy": [
    "customer_id",
    { "field": "created_at", "dateGranularity": "month" }
  ],
  "aggregations": [
    { "function": "sum",   "field": "amount", "alias": "total_sales" },
    { "function": "count", "alias": "order_count" }
  ],
  "having": { "total_sales": { "$gt": 10000 } },
  "orderBy": [{ "field": "total_sales", "order": "desc" }],
  "limit": 25
}

Sorting in the query string: ?orderBy=-priority,created_at — descending priority, then oldest first.

See also

  • REST API — the endpoints that accept ObjectQL
  • Field Types — what each field stores, and so what it can be filtered on
  • CEL — the expression language inside $cel