Contract vs schema
A schema describes structure. A contract specifies behaviour and ownership.
The distinction matters because integration failures are rarely structure problems. The field exists. The type is correct. The format is right, most of the time. The failures happen at the edges: the record where the field is absent, the value that falls outside the expected range, the situation nobody thought to specify. A schema does not cover these. A contract does.
What a contract covers that a schema does not
Five things a data contract specifies beyond structure
Missing field behaviour: what happens when a required field is absent, reject the record, apply a default value, flag for human review, or retry after a delay.
Allowed value sets: not just the data type but the specific values that are valid. "String" is a schema answer. "One of: active, inactive, pending" is a contract answer.
Failure ownership: when a record violates the contract, who is responsible for resolving it, the sending system, the receiving system, or a shared queue with a named owner.
Change notification: what happens when either system changes a field name, deprecates a value, or adds a required field. The contract defines how changes are communicated before they break the integration.
Validity checks at runtime: the contract is not just a design document. It should be verifiable. The integration checks incoming data against the contract at runtime and surfaces violations as they occur rather than letting wrong data accumulate silently.
When to write it
The contract comes before the code. If both sides cannot agree on it, the integration is not ready.
A data contract forces disagreements to surface at design time: writing it together reveals that the two teams assume different things about what the data means. On paper that costs a conversation; in production it costs a debugging project.
