Handoffs between tools

Without a contract, a data handoff breaks in three predictable ways.

A data handoff is just a contract applied to one transfer point, where a record leaves one tool and enters the next. When that point is undefined, the same three gaps appear, and the receiving system cannot see any of them until the bad record has already travelled. The contract closes them at the boundary, where repair is cheap and context is still fresh.

Missing

A required field arrives empty

The next tool accepts the record, but someone must later guess the missing owner, status, or next action.

Changed

Two tools name the same state differently

One tool says active, another says live, and reports need manual mapping before anyone trusts them.

Silent

A failed transfer is invisible

A sync error, rejected import, or skipped record quietly opens a gap between the two systems.

Where the hard problems surface

Four steps to a data contract that prevents integration failures.

A data contract does not need to be long. It needs to be specific. The goal is to make every assumption about the data explicit so that disagreements between systems are caught in the document rather than in production.

  1. 01

    List every field that will cross the boundary

    Start with the fields the receiving system needs - not the fields the sending system has. For each field, write down its name in both systems (they often differ), the data type it should arrive as, and whether it is required or optional. This step alone reveals most naming conflicts and type mismatches before any code is written. A field named "owner" in the CRM may correspond to "assigned_user_id" in the automation tool, with different formats and validation rules.

  2. 02

    Define allowed values for every enumerated field

    Any field with a fixed set of possible values - status, category, type, stage - should have those values listed explicitly in the contract, along with the mapping between how the sending system labels them and how the receiving system expects them. A status of "In Progress" in the CRM may need to arrive as "active" in the receiving system. Without the mapping, the integration will either pass the wrong label or fail silently on values it does not recognise.

  3. 03

    Specify null and missing field handling

    For every field in the contract, decide: what should the integration do if this field is absent or null in the source? Options include applying a default value, rejecting the record and logging it for review, passing the null through, or using a fallback field. This step forces the most important conversation most integrations skip: what does a malformed or incomplete record mean for the receiving system, and who decides how to handle it?

  4. 04

    Define the failure path explicitly

    The data contract is not complete until it specifies what happens when a record fails to meet the contract - when a required field is missing, when a value falls outside the allowed set, when the format is wrong. The failure path should name: where the failure is logged, what information is logged, who is notified, and what the process is for correcting and reprocessing the failed record. An integration without a defined failure path handles contract violations by accident, not by design.

The real value

A data contract is not documentation. It is a structured conversation that forces the right questions before the build.

The value is less the document than the act of writing it: getting the source-data owner and the destination owner to agree surfaces the naming conflicts and missing fields that would otherwise fail in production months later.

After the build

The data contract is maintenance documentation, not just a pre-build artifact.

The most common mistake with data contracts is treating them as a one-time deliverable that gets filed after the integration launches. A data contract that reflects the state of the integration at launch but is never updated becomes misleading - it describes how the integration was supposed to work rather than how it works now. That is more dangerous than having no contract at all.

Keeping it current

How to maintain the data contract after launch

Store it where the integration owner can find it without asking the builder - not in a personal folder or a tool only the builder has access to.

Update it whenever either system changes a field name, adds a required field, or modifies the allowed values for an enumerated field.

Review it when the integration starts producing unexpected output - the contract is often the fastest way to identify what changed.

Treat a contract that no longer matches the integration as a maintenance debt with a specific cost: the next person to debug this integration will spend extra time reconstructing what the contract should say.

Watch the handoff's health signals after launch, skipped records, manual edits, and review-queue volume. Those numbers show whether the contract is still holding or quietly drifting out of date.

Common questions

Questions about data contracts

Every integration needs the conversation the data contract forces. For simple, low-volume integrations, a short document or a shared notes page may be enough. For integrations that carry heavy operational weight, order processing, customer data sync, financial reporting, a formal contract with explicit failure handling and a named owner is worth the overhead. The formality should match the consequence of the contract being broken.

The owner of the source system, the owner of the destination system, and the person building the integration. Each brings a different view: the source owner knows what fields mean and how they are maintained; the destination owner knows what they need and in what form; the builder knows what is technically feasible and where transformations will be needed. The contract fails if any of these perspectives is missing.

The integration should detect the violation and route it to a review queue rather than silently processing incorrect data. That requires the contract to include failure handling rules: what to do when a required field is missing, when a value is out of range, when a field format changes. A contract without failure handling is an agreement about the happy path, useful, but incomplete.

Strict about behaviour, sparse about requirements. Require the smallest set of fields the receiving system genuinely cannot work without, and let the rest be optional, because every field you mark required is a field that can reject a real record on a bad day. Bound what you do accept: a maximum length on a text field, a range on a number, an explicit allowed-value set on an enum. An over-required contract is brittle and rejects good data; an unbounded one accepts a ten-thousand-character name and passes it downstream. The contract should be hard to violate by accident and easy to satisfy honestly.