GaurGaur docs
Contracts

Contracts

A contract is a governed interface to analytical data, and the thing consumers actually query.

A contract is the centerpiece of Gaur: a named, validated definition of what callers may query on a dataset and exactly how each value is calculated. Contracts are the only thing consumers see. Tables and models sit behind them.

Why contracts

Tables and models are flexible, which makes them easy to query inconsistently. Two teams join the same tables slightly differently and get different revenue numbers. An AI agent writes SQL that quietly double-counts. The data is fine; the interface is the problem.

A contract removes that freedom on purpose. It declares a fixed set of dimensions and measures, defines each measure's calculation exactly once, and validates that the whole shape is provably correct before it publishes. Every caller then reads the same answer for the same question.

What a contract gives you

  • One definition. A measure like revenue_usd is written once, in one contract. Every app, dashboard, and agent that uses it computes it the same way.
  • Correct, or rejected. The shape of the contract is checked when it's authored; the shape of each query is checked when it runs. Combinations that would silently inflate or skew numbers are rejected with a clear message, never served.
  • A stable surface. Callers depend on the contract's names, not on the underlying schemas. You can refresh data or restructure models beneath a contract without breaking what calls it.
  • Scoped access. Row-level security inside the contract limits what each caller can see, driven by context passed at query time.

What's in a contract

A contract is a JSON document with five top-level parts:

PartPurpose
sourcesThe tables and models the contract reads, and how they join.
dimensionsThe attributes callers may group and filter by.
measuresThe values callers may aggregate.
filtersFixed conditions always applied (every caller sees the filtered view).
rlsRow-level security, evaluated per call.

Anatomy of a contract walks through each part in detail using Jaffle Shop's product_performance as the example.

How a contract is queried

Callers never write SQL against a contract. They send a structured query that names dimensions and measures the contract has declared:

{
  "contract_name": "product_performance",
  "query": {
    "dimensions": [{ "name": "category" }],
    "measures": ["revenue_usd", "cogs_ratio"],
    "filters": [{ "field": "category", "operator": "eq", "value": "jaffle" }],
    "sorts": [{ "field": "revenue_usd", "direction": "desc" }],
    "limit": 50
  }
}

Gaur validates the query against the contract, injects row-level security, compiles it to SQL, runs it against its own copy of the data, and returns governed rows. See Querying contracts for the consumer side.

In this section

Before authoring anything beyond a single-source contract, read Rules and limitations. Gaur rejects unsafe contracts by design, and knowing the rules up front saves rework.

On this page