
Guide to Data Contracts
| 25 min ReadLast updatedCategory: Data Governance | Tags: #podcast, #data contracts, #data products, #dbt
A data contract is an agreement between the people who produce data and the people who use it, written so that a machine can test it. This guide shows what the contract contains, how to enforce it with ODCS and dbt, and how to get started with one team and one data product.
In short: A data contract is an agreement between the people who produce data and the people who use it, written as code so that a machine can test it every time the data changes. The contract gives the producer a small, known cost, and spares the consumers the errors that come when data changes without anyone saying so. The tools for testing the contract exist, and in our projects it is ownership and follow-up that decide whether it works.
When a developer changes a column in a database, a report may fail, a machine learning model may give wrong answers, or a dashboard may stop working. Data flows between systems and people, often without clear agreements.
These errors do not happen because people make mistakes on purpose, but because the dependencies are hidden. Nobody has said what is allowed and what is not. And nobody notices that something has gone wrong until it has gone wrong.
The cost is hard to see, because it lands somewhere other than where the change was made. Andrew Jones, who wrote one of the first books on data contracts, points out that it costs the producer almost nothing to promise nothing about the data. The consumers have to guess the structure, scramble when something changes and fill their pipelines with IFNULL and COALESCE for every variant the data has had. That cost is multiplied by the number of consumers.
A data contract works as an API for data: a specification of structure, quality and expectations that both producers and consumers rely on. It moves a small part of the cost over to the producer, who has to describe the data and keep the description up to date. In return, the cost is known, the same as maintaining an API, and the consumers are spared almost all the errors caused by changes they did not know about.
As platforms become more decentralised and more teams produce their own data products, the need grows for clear, technically verifiable agreements between those who own data and those who use it. In the chapter on interfaces and data contracts in our guide to data products, we write about when a contract pays off, and when less will do.
What problems do data contracts solve?
Data contracts solve three problems. They make the dependencies between teams visible, so that a change that breaks things for others is stopped before it reaches production. They provide a common foundation when data is shared across organisations and sectors. And they make it possible to build larger ecosystems where several parties use the same definitions.
Fewer errors in the data flow
When the dependencies are visible and can be tested, teams can build solutions that are both self-service and reliable.

Monzo, the British digital bank, has published figures from its work with such agreements. More than 100 teams contribute to a data warehouse with over 12,000 dbt models, and the bank introduced what it calls interfaces: a dbt model that a team has declared as a contract other teams can build on. With around 30 per cent of the migration done, Monzo reported around 40 per cent lower costs and around 25 per cent faster delivery of data in some of the domains. The gain comes from the whole rebuild, with fixed modelling layers and automated standards in CI alongside the interfaces, and the bank itself says it is early days. The interfaces also have a cost. The team that owns an interface has to document it, test it and keep it stable, and that is the known cost the producer takes on so that the other teams are spared.
Better support for data sharing
Public and cross-sector requirements also raise expectations of structured data sharing:
- Norway’s new data act, dataforvaltningsloven (in Norwegian) from June 2026, follows up the Official Norwegian Report NOU 2024: 14 (in Norwegian). The act implements the Open Data Directive and the Data Governance Act in Norwegian law. It gives a right to demand that data be made available for re-use, and sets requirements for how metadata is published. The government will decide when the act enters into force.
- PSD2 requires banks to give third parties secure access to account data, in practice through APIs, which has opened up new markets and made sharing safer.
Data contracts are a practical answer to such requirements, and can be seen as a technical implementation of the principles behind the regulation.
More value in larger ecosystems
Data contracts must be understandable and possible to implement. There is a lot to learn here from other standardisation efforts that have proved their value over time:
- HL7 (health): very detailed, but too complicated in practice
- EHF (trade and finance, the Norwegian format for electronic invoices and procurement documents): simple enough to work, and widely adopted
These are examples where data contracts create value across an entire ecosystem. But we would like to see data contracts implemented more like EHF than HL7, with the minimum requirements eventually standardised for a use case, a type of data or an industry.
How do data contracts relate to distributed data teams and data products?
When responsibility for data is spread across several teams, each team owns its own data products, and other teams build on them. The data contract turns the data product into something others can trust. It says what is delivered, at what quality and how often, and it is tested every time the product changes. Data mesh is the best-known model for organising data this way, and we have described its principles in our guide to data mesh.
Data as a product
In a distributed organisation, as in data mesh, responsibility for data is spread across domain or product teams. These teams develop their own data products, often in the form of tables, APIs or datasets, for others to use. Data products therefore need clear properties: standardised, shareable, owned by a team, and managed throughout their life cycle. And remember: not all data qualifies as a data product.

Data products need specifications of properties such as quality, warranty and service, in the same way as physical products:
When you buy an e-scooter, you expect specifications for range, warranty and speed. Without them, the product would be hard to sell and impossible to trust. The same applies to data products. Without clear specifications, data consumers quickly lose trust, and the value declines.
The contract turns the product idea into practice
The data contract is the link that turns “data as a product” into practice. It specifies exactly what is delivered, the quality and the frequency (SLA), and it is used actively in the CI/CD pipeline and in communication between teams. The contract lets the producing team specify what it promises to deliver, and the consuming teams can trust that what they build on will not suddenly change.

What does a data contract look like in practice?
A data contract says who delivers which data to whom, how often, with which fields and quality requirements, and what happens when the requirements are breached. The three examples below are hypothetical, from banking, energy and manufacturing, and all three describe updates, fields, quality requirements, alerts and what the data means.
Example 1: Customer data in banking and finance
A team in a bank delivers customer data as a data product to the risk management department. The data contract specifies:
- Updates: every hour, from 08:00 to 18:00.
- Fields: customer_id, credit_risk, loan_amount, status.
- Quality requirements: no duplicates, at most 0.5% null values.
- Alerts: automatic alerts on breaches, integrated with the bank’s risk management systems.
- Semantic definition: credit risk is calculated from the customer’s credit score, payment history and external data.
The risk team can then trust the data, and detect and handle risk situations faster.
Example 2: Electricity consumption and grid balancing in the energy sector
An energy supplier delivers electricity consumption data from smart meters as a data product to the grid operator for balancing the power grid. The contract specifies:
- Updates: every 5 minutes.
- Fields: meter_id, consumption_kwh, timestamp, customer_type.
- Validation rules: positive values only, and meter_id must exist in the master data.
- Semantics: consumption_kwh refers to actual consumption, not estimates.
- Pricing: internal charging based on data volume and update frequency.
- Alerts: automatic notification to operational control systems if values are missing or outside expected ranges.
This lets the grid operator balance the power grid precisely and reliably in real time, with the costs shared openly.
Example 3: Machine maintenance in industrial production
A production team delivers sensor data for condition-based maintenance of machines to a maintenance team. The contract specifies:
- Updates: every 15 minutes.
- Fields: machine_id, temperature, vibration, operating_hours.
- Data quality: at most 1% abnormal values, 100% coverage of critical machines.
- Alerts: automatic alerts directly into maintenance systems if critical values exceed thresholds.
- Semantic definition: vibration and temperature are used to predict machine wear based on defined limit values.
The maintenance team can then plan maintenance before faults occur, reduce downtime and make better use of its resources.
What does a data contract contain?
A good data contract describes three things: the schema, the business rules and the service level. It also needs a unique ID and a version, the name of the dataset it applies to, documentation and an owner. Once the foundation is in place, it can be extended with privacy, compliance rules, links to business concepts and quality measures.

Data contracts are a practical application of the principle of “governance as code”. They act as contractual interfaces for data, and make it possible to specify and validate expectations of data, ideally as early as possible in development. At best, the contract runs as an integration test in the CI/CD pipeline, so that errors are caught before code and data are moved to production.
Three core components
A good contract always describes:
- Schema: structure, columns, data types and formats.
- Business logic: expected values, tolerance for null values, ranges and domains.
- SLAs: how often the data is updated, for example SLA1 for critical data every 5 minutes and SLA2 for less critical data daily.
The contract should always be validated programmatically in a CI/CD pipeline. Where it is enforced depends on the organisation’s architecture and technology stack, but at a minimum it should be monitored, and there should be a process for what happens when the contract is breached.
The contract as a metadata object
The contract should also clearly state:
- ID and version control: a unique identifier for lookup and reference in pipelines and documentation, and the basis for managing changes.
- Asset name and namespace: which dataset or data asset the contract applies to. This should be 1:1 (for example
vehicle_statusin thetransportdomain). - Documentation: what does the data mean, and how is it used? Documentation should be mandatory.
- Owner: the producer is responsible as owner, and the contract is developed together with the most important consumers.
Once the foundation is in place, you can extend it with:
- PII classification and privacy requirements
- compliance rules
- links to taxonomies and ontologies
- a description following DCAT-AP-NO, the Norwegian standard for describing datasets in data catalogues
- quality measures, for example following DQV-AP-NO, which uses dimensions such as completeness, accuracy, consistency and currentness
How good the data needs to be is decided by what it will be used for. We write more about that in Data quality: how good does the data need to be, and who decides?
A data contract is not just a specification. It is a basis for testing, a governance tool and an important link between people and systems in a modern data organisation. You can see the contract as an enhanced version of a schema, with semantics, validation, context for use and governance built in.
More on semantics and taxonomy
Data contracts often describe a single entity, such as “customer”. But for this to be meaningful, it should be linked to a semantic structure, a taxonomy or a concept model. In ODCS, the contract, its tables and its fields can point to a definition outside the contract, for example in a business glossary or a data catalogue.
By linking contracts to concepts and taxonomies, teams gain reuse and a shared understanding. “Customer” can then be a type of “individual party”, and the contract can inherit rules or definitions from it.
What standards and tools are there?
The open standard for data contracts is the Open Data Contract Standard (ODCS), in which the contract is written in YAML. Data Contract CLI tests the contract against the data, and dbt can enforce the schema every time a model is built. For events and APIs, formats such as Avro, JSON Schema and Protobuf are used. The contract should live as code, alongside the code that produces the data.
Open Data Contract Standard
ODCS is maintained by Bitol, a project in the Linux Foundation AI & Data that reached the foundation’s highest maturity level (graduated) in July 2026, and is open source under Apache 2.0. When version 3.1.0 arrived in December 2025, the maintainers of the Data Contract Specification phased out their older format in favour of ODCS. Version 3.2.0 arrived in September 2026.
This is how the banking example above could look in ODCS, shortened:
apiVersion: v3.2.0
kind: DataContract
id: customer-risk
name: customer_risk
version: 1.0.0
status: active
domain: customer
team:
name: customer-data
servers:
- server: production
type: snowflake
account: bank-prod
database: CUSTOMER_DATA
schema: RISK
schema:
- name: customer_risk
physicalType: table
properties:
- name: customer_id
logicalType: string
required: true
unique: true
- name: credit_risk
logicalType: number
description: Calculated from credit score, payment history and external data
quality:
- metric: nullValues
mustBeLessOrEqualTo: 0.5
unit: percent
slaProperties:
- property: frequency
value: 1
unit: h
Data Contract CLI
Data Contract CLI is an open-source command-line tool built on ODCS. It checks that the contract is valid, connects to the data source listed under servers in the contract, and runs the schema and quality tests against the data, in Snowflake, Databricks, BigQuery, Kafka and Postgres, among others. Version 1.0 arrived in June 2026. If you run the tool in the CI/CD pipeline, the contract becomes a test and not just documentation:
datacontract test customer-risk.odcs.yaml
dbt contracts
dbt can enforce the schema when a model is built. With contract: enforced: true, every column must have a name and a data type, and the build stops if the query returns other columns or types than the contract states. The tests for the content sit alongside, under data_tests. The arguments syntax requires dbt 1.10.5 or later, and in older versions values sits directly under the test:
models:
- name: transaction
config:
contract:
enforced: true
columns:
- name: transaction_id
data_type: string
constraints:
- type: not_null
data_tests:
- unique
- name: status
data_type: string
data_tests:
- accepted_values:
arguments:
values: ["NEW", "COMPLETED", "CANCELLED"]
A dbt contract covers the structure. It says nothing about how often the data should be updated, which quality requirements apply over time, or who owns the data. It is therefore part of the data contract, not all of it.

Testing tools and formats
- Great Expectations (GX Core) is used for declarative data tests. The source code now lives in Fivetran’s GitHub organisation, and the project is still open source under Apache 2.0.
- Soda Core is used for data checks, but is licensed under the Elastic License 2.0 and is therefore not open source in the usual sense.
- Avro, JSON Schema and Protobuf are used for contracts in APIs and messaging systems.
What does the workflow for a data contract look like?
The workflow starts with the consumer who needs something, goes via the producer who confirms that it can be done, and ends with a contract in code. After that, every change is checked automatically against the contract. If the change breaches the contract, the owner is alerted, and the change follows a fixed breach protocol.
As the figure shows, the workflow for data contracts can consist of the following steps:
- The data consumer identifies a need or a limitation in the data.
- The data consumer requests a data contract for a given data asset.
- The data producer confirms that the data contract is feasible.
- The data contract is confirmed and formalised in code.
- The data producer opens a pull request to change the data asset.
- The change is checked automatically to see whether it breaches existing data contracts.
- The change either breaches a contract or it does not: a. If the data contract is breached, the owner of the data asset is alerted, and the change is handled according to a breach protocol. b. If the change does not breach the contract, the data asset is updated for further processing.

What are the most common pitfalls?
The most common pitfall is a contract that is only documentation. It is not tested, it changes without versioning and it has no clear owner, so it stops matching the data without anyone noticing. Then the cost is back with the consumers. A good contract is machine-readable, testable, versioned and owned by the producing team.
Another pitfall is placing the contract where the problems become visible, between the data warehouse and the reports. There it has to chase data that has already changed. Mark Freeman II, one of the authors of the book Data Contracts, describes a self-service analytics project he had to stop after six months, because the analytics database was a day behind the production of data in the source system, and so did not keep up with the changes. The contract should sit as close to the source as possible, in the code that changes the database. Data from suppliers and others outside the organisation cannot be stopped at the source, and there a breach should be quarantined before the data moves on.
Typical pitfalls:
- The contract is only documentation, and it is not tested
- Changes happen without versioning, and what the consumers have built breaks
- No clear owner
- Nobody follows up when the contract is breached, so the alerts pile up
- The contract sits where the errors become visible, far from where they occur
- The dbt contract is mistaken for the whole data contract, even though it only checks columns and types
A good contract:
- is machine-readable
- is testable
- is versioned
- has ownership anchored in the producing team
- has the backing of the most important consumers
- has a clear process for managing changes
Does the producer or the consumer own the contract?
Formally, the contract is owned by the producer. It is the team that manages the data product that publishes the interface. But good practice is to draw up the contract together with the consumers, for example in joint meetings or pull requests. The contract should be precise and stable, and changes must happen through versioning, so that existing consumers keep working.
Ownership follows the cost. Only the party that can change the data can promise anything about it, and that is why the producer must write and maintain the contract. In return, the consumers no longer have to guess the structure and scramble every time it changes. In the article on data ownership, we write about who should own the data itself, and what it costs when nobody does.

What we see at Glitni
At Glitni, we use data contracts in our projects, and the technical side is not what decides whether they work. We get the schema, the tests and the check in the CI/CD pipeline in place with the tools above. The hard part is ownership and follow-up: that someone owns the contract over time, and that someone follows up when it is breached.
That is where the cost from the opening lies. Writing the contract is a one-off job, while owning it is part of operations, with breaches to handle and new needs from the consumers to bring into the next version. The automated part is still needed, because without tests nobody knows the contract has been breached. But tests alone do not make anyone an owner.
What changes when the consumer is an AI agent?
An AI agent takes the contract literally. It does not ask about what it does not know, but fills the gaps with its own assumptions. From version 3.2.0, ODCS has a dedicated block, context, where the producer can write how the data should be used, which questions have verified answers, and what an agent must never do with the data.
context:
instructions: >
Use the table to assess credit risk in the portfolio.
Credit risk is the bank's own calculation, not a rating from a credit bureau.
verifiedStatements:
- question: "What share of the loan amount has high credit risk?"
constraints:
- constraint: "Never show individual customers in an answer. Group at segment level or above."
Freeman has tried this in a workshop repository for the book. A few of us at Glitni attended a course with him at Helsinki Data Week in October 2026, and he told us about a test he had run. An AI assistant writes SQL against a database of objects from the Metropolitan Museum of Art. The source has four labels for furniture, and a fifth that looks similar refers to a fitting on a sword. Without help, the assistant answered 1 in 10 questions about such categories correctly. When the contract was given a profile stating which labels belong to each category, and the prompt was built from that profile, it answered 9 in 10 correctly. At the same time, the simple questions dropped from 9 to 7 correct, and Freeman calls the result a single run and a demonstration, not proof.
The key point is that meaning can now be tested in the same way as the schema. If someone removes one of the furniture labels from the prompt, the check in the pull request fails and names the missing label, without the model having to run. A ready-made ontology from the field is not enough on its own. The first time Freeman added Linked Art, an ontology made for museums in general, the answers got worse, because it lacked the material wood, which the museum uses. The context has to be made for the data it is meant to explain.
The same idea runs through the article on metadata and ontology, where a semantic layer for AI becomes a contract between the team and a recipient that takes everything literally. When agents write parts of the code in a data pipeline, we at Glitni believe that the tests, the data contracts, the catalogue and the dbt project are the core the agent is steered by and measured against. The better that core is, the less it matters which model is running.
How do you get started?
Choose a data product where an error in the data has cost something before, and the team that owns it. Write down what you in practice promise the consumers today, put the contract in code and let it run in the CI/CD pipeline. Extend it with more requirements and more teams once the first contract has shown that it catches errors.
Introducing data contracts requires organisational backing and support from senior management. Putting contracts in place takes time and priority, but less than the time you spend cleaning up after failures.
How you make the case depends on who you are talking to. Andrew Jones says that with a CDO or the head of data governance, he leads with the data owner classifying the data in the contract, so that the platform can enforce the rules for retention, access and quality automatically. With a data owner, he leads with the contract letting them share their data without becoming experts in data management. The features are the same, but the pitch is different.
Freeman believes it is a lost battle to get the developers who create the data to care about it. They care about the system being stable and about not being woken up at night. The contract has to fit into the tests and the CI/CD pipeline they already have. Freeman advises against stopping the pipeline straight away. At first, contract breaches go only to the data team, and after a month or two you have a log of concrete breaches per dataset to present. The next step is a comment in the pull request that does not block the change, and hard stops are used only where a contract breach carries a significant cost. That way the contract gets to show its value, even before it stops anything.

Some tips from practice:
- Decide who owns the contract and who follows up when it is breached, before you choose tools
- Start with one team and one data product
- Let breaches go to the data team as alerts at first, and let the contract block changes only once the log shows what the breaches cost
- Share success stories internally
- Get support from the CDO or the person responsible for data from the start
- Use tools and formats you already have (such as dbt, Terraform and Databricks), and add Data Contract CLI for the tests
Start small. Formalise what you already do. Then gradually build up technical validation and a culture of sharing and ownership.
Would you like help writing your first contract? Get in touch with us at Glitni.
Frequently asked questions about data contracts
What is a data contract? A data contract is an agreement between the team that produces a dataset and the teams that use it, written as code so that it can be tested automatically. It describes the schema, the quality requirements, how often the data is updated and who owns it. The contract works as an API for data. The producer can change what lies behind it, as long as what the contract promises still holds.
Is a dbt contract the same as a data contract? No. A contract in dbt checks that the model returns the columns with the names and data types you have defined, every time the model is built. It says nothing about quality requirements over time, how often the data is updated or who owns it. The dbt contract can be the part of the data contract that enforces the schema, but it is not the whole contract.
Who owns the data contract? The producer, meaning the team that manages the data product and publishes the interface. The producer bears the cost of describing the data and keeping the contract up to date, but the contract should be written together with the most important consumers. Changes happen through versioning, so that consumers using an older version keep working.
What is the hardest part of introducing data contracts? Ownership and follow-up. The schema and the tests can be set up with ODCS, Data Contract CLI or dbt. In our projects, what decides the outcome is whether someone owns the contract over time, follows up when it is breached, and brings new needs from the consumers into the next version.
Which standard should we use for data contracts? The Open Data Contract Standard (ODCS) is the open standard, maintained by Bitol in the Linux Foundation AI & Data. The contract is written in YAML, and version 3.2.0 from September 2026 also has a dedicated block with context for AI agents. Data Contract CLI can test an ODCS contract against the data in Snowflake, Databricks, BigQuery and Postgres, among others.
When do we need a data contract? When several teams depend on the same data, when an error is costly, and when the data changes often. The more of this that applies, the stronger the case for writing a contract. In many cases it is enough for a long time to start with the fields people misunderstand, the keys and how changes are announced.
Listen to the episode on data contracts
In episode 15 of the podcast “Datautforskerne” (in Norwegian), Safurudin Mahic and Magne Bakkeli talk about data contracts. The episode is available on Spotify, Apple and Acast. Like and subscribe!
Sources
- Antonia Badarau, Irina Mugford and Massimo Frangiamore: A “meshy” approach to Data: Enabling 100+ teams to build Data Models, Monzo, 22 April 2026.
- Andrew Jones: Schema-on-read vs schema on write: It’s about the costs, newsletter, 18 September 2026.
- Andrew Jones: How to frame data contracts, newsletter, 11 September 2026.
- Andrew Jones: Data Contracts: The API for data, apidays Paris, December 2023. The figure without and with a data contract is adapted from two figures in this talk.
- Andrew Jones: Implementing domain ownership with data contracts, 16 May 2025, and Defining data products with data contracts, 23 May 2025, newsletter.
- Andrew Jones: Driving Data Quality with Data Contracts, Packt, 2023.
- Chad Sanderson, Mark Freeman and B. E. Schmidt: Data Contracts: Developing Production-Grade Pipelines at Scale, O’Reilly, November 2025.
- Mark Freeman II: masterclass on data contracts and semantic contracts, Helsinki Data Week, 26 October 2026, and the workshop repository semantic-contracts-workshop, read 26 October 2026.
- Bitol: Open Data Contract Standard, the release notes for version 3.2.0, 8 September 2026, and Bitol graduates, 28 July 2026.
- Data Contract CLI, with its documentation.
- dbt Labs: Model contracts and Data tests, documentation, read 16 October 2026.
- Great Expectations and Soda Core, GitHub, read 16 October 2026.
- NOU 2024: 14 Med lov skal data deles, Ministry of Digitalisation and Public Governance, 2024, and dataforvaltningsloven, Act of 19 June 2026 No. 36, both in Norwegian.
- Norwegian Digitalisation Agency: DCAT-AP-NO, DQV-AP-NO and the vocabulary of quality dimensions.
- datacontract.com, which the figure of a data product with a data contract is adapted from, retrieved 13 July 2025.
