Query, search and analytics
Open in
Query, search and analytics read the record at volume: one query grammar on every list, search indexes, metrics, reports, and sinks that stream it out.
Every read is masked by the caller's Role before it answers. Filled: what a reader sees.
Reading the record at volume
Every read below answers on every Interface and shows only what the caller's Role may see. An empty or partial answer says why.
| Family | What it does |
|---|---|
| One query grammar | Every list takes where (equality, ranges, sets, text, across Relationships), sort, group, count, sum, avg, min, max, fields, limit and cursor; the same words over the API, MCP, the SDK, the CLI and a view |
| Search indexes | search per Noun: words, typo-tolerant and per language; meaning, kept in the Customer's own Namespace; and facets with their counts. One search across Nouns ranks both |
| Views | A saved filter and sort as data, served over every Interface with its count; grouping and totals are the query grammar's or a metric's |
| Metrics | One layer of measures (sum, count, avg, a ratio of two), dimensions (group), time grains (by) and filters, defined once in the file and answered the same everywhere |
| Comparisons | Any metric for two periods, or against a target the Customer sets, with the change between them |
| Reports | Saved metrics sent on a schedule to members by email or to a webhook, and any view or metric as a file on demand |
| Sinks | Continuous export of traces, logs, Events, the sales record, the audit log and a Namespace's change data, to OpenTelemetry, a SIEM, object storage or a warehouse |
| Two owners of sinks | You stream your product's own data on the Operator plane; each Customer streams its own Namespace's records and audit log, on its own Interfaces |
A view, a metric and the UI contracts read this one grammar. A chart a UI draws and a number an agent asks for agree.
Example
Deals searched by title, meaning and stage; won value and win rate by month; and a weekly report to every member.
import { define } from 'apis.dev'
/** Deals for each Customer, kicked off when won. */
export default define({
name: 'pipeline', domain: 'pipeline.apis.dev',
Company: { name: 'string', domain: 'url!#', deals: '<-Deal.company' },
Deal: {
title: 'string', amount: 'decimal(12, 2)', company: '->Company.deals', notes: 'markdown? ',
stage: { open: [], qualify: 'opened', win: 'qualified', lose: ['opened', 'qualified'] },
},
search: { Deal: { text: ['title'], meaning: ['notes'], facets: ['stage'] } },
metrics: {
won: { sum: 'Deal.amount', where: { stage: 'won' }, by: 'month', group: ['company'] },
wins: { count: 'Deal', where: { stage: 'won' }, by: 'month' },
closed: { count: 'Deal', where: { stage: ['won', 'lost'] }, by: 'month' },
winRate: { ratio: ['wins', 'closed'], by: 'month' },
},
reports: { weekly: { metrics: ['won', 'winRate'], every: 'every Mon 08: 00', to: 'email' } },
offer: { Team: { month: 49, seats: 5, seat: 9 }, 'Deal.open': 0.001 },
})A member's agent asks for the win rate by month; the answer says how current it is.
HTTP/1.1 200 OK
Content-Type: application/ json
X-Cost: price= 0, currency= "USD"
X-Request-Id: req_0b9d4f27e61a8c53d2e8
{
"metric": "winRate",
"by": "month",
"items": [
{ "month": "2026-08", "value": 0.29 },
{ "month": "2026-09", "value": 0.34 },
{ "month": "2026-10", "value": 0.31 }
],
"total": 3,
"asOf": "2026-10-27T09: 00: 00Z"
}That is GET /metrics/, getMetric over MCP and pipeline metrics get winRate --by month in the CLI.
Metrics, reports and what a product tells you
A metric is defined once, in the file, and every reader gets the same number.
What your product tells you is a set of these: callers, the funnel, revenue, work and runs, each rebuilt from the record.
| Reader | What it gets |
|---|---|
| A Customer's member | Metrics and views over its own org's records, masked by its Role, in the portal, any UI and the API |
| A Customer's admin | The same across child orgs its org graph rolls up, and a sink of its own Namespace to its own warehouse |
| You | Your product's signals across every Customer, without any Customer's private fields, and sinks of your own data |
| An agent | Any metric or query by Verb, with asOf on each answer so it knows how fresh the number is |
| A tool outside the product | Sinks and the change feed: it reads the product through them and acts through its Verbs |
Indexes, reports and sinks, state by state
Each is a Thing with Verbs on the product's API, MCP server and CLI, and each move writes its Event.
| Thing | States | What moves it |
|---|---|---|
| A search index | building, current, behind, rebuilding | A deploy that adds or changes it; the Events it reads; a reply names how far behind it is |
| A metric answer | current or behind, with asOf | The Events it reads; a period that has not closed is marked open |
| A report | scheduled, sending, then sent or failed | Its schedule, in each Customer's timezone; a failed send retries, then falls back to another channel |
| A sink | configured, backfilling, flowing, then lagging, failed or paused | Sink.create, then Sink.backfill from a point in time; a target that refuses holds the data and retries |
| A sink's schema | Follows the Version it ships in | A deploy; a breaking change opens a new schema version beside the old one |
Every sink keeps what it could not deliver for seven days, and Sink.backfill sends any range again.
What members, admins and agents meet
- A member. Filter, group and total any list, search by words or meaning, and never see a record their Role hides.
- An admin. One report each week, and the org's records and audit log flowing to its own warehouse and SIEM.
- You. Traces and logs in your own observability tools, and the sales record in your own warehouse.
- An agent. The same query words on every tool, metrics by name, and
asOfon every number.
Every list, search, metric and sink reads one record through one grammar, so a chart, a report and an agent's answer always agree.