What a data contract is
A data contract is the written agreement between whoever produces a dataset and whoever consumes it: what gets delivered, in what shape, what it may be used for, and when it is available.
The most useful analogy is an API. Nobody integrates a service without knowing what it returns and what it guarantees. With a table, the usual way to learn the rules is the day something breaks: someone renamed a column, stopped tagging a sensitive field, or moved the load schedule, and another team's dashboard woke up wrong.
The idea people mix up the most: a contract is not a data quality test suite. Quality tells you whether the data is correct. A contract also tells you who answers for it, which columns are guaranteed, what it may be used for —by an AI agent too— and whether it is still governed. Quality is one part of the contract, not the contract.
What goes inside
A complete contract has seven parts. The difference that matters is which ones a tool can check and which ones stay declared in writing:
| Part | Checked? | What it adds to governance | What it says |
|---|---|---|---|
| Details | — | Someone answers for the promise | Name, owner and description |
| Terms of use | No | The purpose of the data, which no quality test looks at | Allowed and forbidden uses, AI agents included |
| Schema | Yes | Change control: the producer knows what not to touch without notice | The columns that are guaranteed |
| Semantic rules | Yes | Governance that stays in place, not just governance applied once | Conditions on the table's metadata: owner, tags, domain |
| Security | No | Who the data is meant for | Classification, who consumes it and which rows they see |
| Quality | Yes | Correct data | The tests that are part of the agreement |
| Service level (SLA) | No | When the data can be relied on, and for how long | Refresh frequency, latency, availability time, retention |
The table follows OpenMetadata's structure. The open standard for contracts, ODCS (Open Data Contract Standard), organizes equivalent pieces —schema, quality, service levels, team, roles— so that a contract can travel between tools.
Proof that it is not just quality
An example on a customer table with practice data. The contract has three semantic rules —the table has an owner, it is tagged as personal data, it belongs to its domain— and two quality tests: unique identifier and non-null email.
It was run three times. Before the second run, the table's sensitive-data tag was removed. The data did not change and the quality tests stayed at 100%. The result:


The contract failed and named the rule, while quality stayed green. A test suite on that table would have said nothing: the data was fine. What broke is that the table stopped being governed —for search, access policies and any agent querying it, it became just another table— and that is exactly what a contract watches and a quality test does not.
How to write one in OpenMetadata
The screenshots come from OpenMetadata 1.12 on a sample database; in newer versions some labels may move around. The full step-by-step, with every option, lives in the official documentation (link at the end). What follows is the walkthrough with the reasoning behind each step.
Before you start: the table already cataloged and curated —with owner, domain and tags—, because the contract does not set those: it checks that they are there. The quality tests must also exist on the table already. To run the contract you also need OpenMetadata's ingestion service up: quality tests run there.
1. Open the wizard. On the table page, Contract tab → Add Contract. There are three ways to create it: write it in the UI, or import it in OpenMetadata's own format or in ODCS.

2. Details: who answers for it. The title works as an identifier —it becomes part of the contract's full name—, so keep it without spaces or accents. The owner is usually a team. Fill this tab in first: the Save button turns on as soon as you visit the rules tab even if the title is empty, and if you press it, what you get is a technical server message, not a "title is missing".

3. Terms of use: what it may be used for. This is the only place where the allowed use of the data gets written down. Three paragraphs work well: allowed use, forbidden use, and what an AI agent may do with the table.

4. Schema: what is guaranteed. Tick the columns consumers actually use, not all of them. Each ticked column is a commitment; the producer can change the rest without breaking the agreement.
5. Semantic rules: the heart of the contract. Each rule has a name, a description and a condition built with three dropdowns: field, operator and value. The available fields are table metadata: owner, description, tags, criticality tier, domain, data product, among others.

Two rules of thumb. One rule per thing: when the contract fails it shows the name of the rule that was not met, so three separate rules tell you what broke, while one rule with everything inside only tells you that something did. And write the description as the explanation someone will read when they find the contract in red, because that text is stored as the reason.
6. Security: who it is meant for. Classification, access policy, identities and row filter. All of it is free text: the classification is not taken from the catalog's tags and the policy is not enforced. It is a declaration.

7. Quality. Pick, among the tests that already exist on the table, the ones that are part of the agreement. OpenMetadata creates a dedicated runner for the contract and deletes it along with it.
8. Service level. Refresh frequency, maximum latency, the time of day the data must be available, retention, and the column that records when each row was updated.

9. Save and run. Once saved, the contract is approved: the wizard has no review step. Saving does not run it; the gear icon at the top has Run now, and OpenMetadata also ships an application that runs every contract once a day. With a result, the boundary from the table above shows on screen: schema, semantic rules and quality get a status; service level and security get none.

Every run stays in the contract's history. In the example: pass, fail, pass.

What to know before you trust it
Measured by running it, not read in a brochure:
- Three of seven parts are checked. Schema, semantic rules and quality. Terms, security and service level stay written next to the data, and enforcing them depends on other controls: permissions, freshness monitoring, usage review.
- A type change does not fail the contract. The schema fails if a guaranteed column disappears, but if it changes type it stays green: from an integer to text it gets noted as a difference; from an integer to a larger integer, not even that.
- It is born approved. If your organization needs formal approval of a contract, that happens outside the tool.
- Exporting to ODCS loses the governance part. A contract written in the UI exports without the terms-of-use text, the semantic rules or the quality rules. To move it to another OpenMetadata installation, the native export (Export) carries it complete.
When it is worth writing one
It is worth it when several teams or AI agents consume a table, when it holds sensitive data, or when the producer's changes have already broken something downstream. That is where the contract turns into a rule what today is a conversation that gets forgotten.
Not yet, if the table has no owner or tags: the contract checks governance that has to exist first. The first step is cataloging and curating (OpenMetadata). It also does not pay off on a table only its producer uses: there is nobody on the other side of the agreement.
And if all you need is to prove the data is correct, what you are looking for is a data quality tool, such as Great Expectations: the contract starts where that question ends.
Going deeper
- Official OpenMetadata documentation on data contracts: docs.open-metadata.org — Data Contracts
- ODCS, the open data contract standard: github.com/bitol-io/open-data-contract-standard