Why this exists

A canonical tag drifting from a sitemap. A Type 2 dimension with an off-by-one boundary. A metric quietly redefined by an app release nobody on the data side reviewed. Three unrelated-looking problems, three different root causes - and the same missing thing underneath all of them: nobody had written down, in a place both sides were obligated to check, what the data was actually supposed to be.

A data contract is that written-down thing. Not a legal document - an explicit agreement between whoever produces a dataset and whoever consumes it, covering what the data means, who's accountable for it, how it's allowed to change, and what happens when it breaks. Most teams don't have one. Most teams don't notice until something like the three problems above shows up first.

What the discipline actually covers

"Data contract" gets used loosely enough that it's worth being specific about what it actually needs to contain to do any good. It's fewer than four things, and none of them are exotic.

Ownership

Every dataset that other teams depend on needs a named owner - not a team name, an actual person or role accountable for it. Without that, a breaking change ships from whoever happened to touch the code last, and consumers find out by their dashboard breaking rather than by being told.

Versioning

A schema or a definition doesn't get changed in place - it gets versioned, the way an API does. A backwards-incompatible change ships as a new version consumers opt into on their own timeline; a compatible change gets documented and dated. The alternative is what a Type 2 boundary bug or a silently redefined metric both look like from the consumer's side: the same name, quietly meaning something different underneath.

SLAs

Freshness, completeness, and accuracy need an explicit, agreed-on standard - how current the data is expected to be, what "complete" means for that specific dataset, and how quickly a violation gets acknowledged and fixed. Without a stated SLA, "the dashboard is a day behind" is either a non-issue or an outage depending entirely on who you ask, because nobody agreed in advance which one it is.

A real review gate

A change that affects a contract - a column, a firing condition, a definition - needs to require sign-off from the consumer side before it ships, not just a notification after the fact. This is the single piece that would have caught the semantic drift case directly: the event's firing condition changed inside a release that never crossed paths with anyone who reported on it.

Why this gets skipped so often

Nobody sets out to skip it. A dataset starts as an internal implementation detail with one consumer who sits three desks away, and an informal handshake is genuinely enough. It stays informal past the point where it's still enough, because nothing forces a review of that decision - the data keeps flowing, the dashboards keep rendering, right up until a producer-side change crosses a boundary nobody had drawn.

By the time a contract would obviously help, there are usually several consumers, at least one of whom nobody producing the data has ever spoken to directly. Retrofitting ownership and review gates at that point is a bigger lift than it would have been at the start - which is exactly why it's worth treating as a default from the first consumer, not a response to the third incident.

What adopting it actually looks like

None of this requires new tooling to start. In most cases, it's:

  • Naming an accountable owner for every dataset with more than one consumer, and making that ownership discoverable, not just known informally.
  • Writing down what each critical field or event actually means, including the conditions under which it fires or gets populated - the exact thing that was missing in the semantic drift case.
  • Requiring a version bump or an explicit changelog entry for any change that alters meaning, not just structure.
  • Adding one review step - even a lightweight one - before a producer-side change ships, specifically for anything a contract covers.

The goal isn't paperwork for its own sake. It's making sure that when a definition changes, it changes as a decision both sides made together, instead of an accident one side discovers later. Establishing that discipline is part of the Analytics & Data work done alongside every new integration.

Frequently asked questions

Is this only necessary at large-scale, multi-team organizations?

The formal version scales with team size, but the underlying discipline applies as soon as there's more than one consumer of a dataset who isn't also its producer - which happens well before an organization would call itself "large-scale."

How is this different from just documenting the schema?

Schema documentation describes structure. A contract also covers ownership, versioning behavior, and freshness expectations - structure was never the part that failed in any of the incidents that make this worth doing; the agreement around how it's allowed to change was.

What's the smallest version of this worth starting with?

A named owner and a one-paragraph definition for each dataset other people depend on, plus an agreement that changes to either get communicated before they ship rather than discovered after. That alone catches most of what actually causes incidents like the ones documented elsewhere in these notes.

Not sure who actually owns your most-used datasets?

A short conversation is usually enough to tell whether there's a quick answer or something deeper worth tracing.