Skip to main content
Design‑to‑Engineering Signoff for Complex Integrations: Integration Contracts, Acceptance Criteria and a Lightweight Signoff Ritual

Design‑to‑Engineering Signoff for Complex Integrations: Integration Contracts, Acceptance Criteria and a Lightweight Signoff Ritual

How to turn "looks good, ship it" into a real contract when three or more systems have to agree on data, failure, and timing

Most signoff processes work fine right up until more than one system is involved. A single feature inside one codebase? A designer and an engineer can eyeball it and move on. But the moment you're integrating a billing platform with a CRM, a warehouse system with a shipping API, or a scheduling tool with a payments processor — "yeah that works" quietly becomes the most expensive sentence in the whole project.

The failures don't show up in the demo. They show up three weeks later when a refund event fires and nobody agreed on what a "cancelled" order actually looks like in the payload.

This post is narrowly about that: how to make the design-to-engineering handoff enforceable when multiple systems have to cooperate. Not a broad governance guide. Just the contract, the acceptance criteria, and a signoff ritual light enough that people will actually run it.

Where multi‑system signoffs actually break

Single‑system signoff is a conversation. Multi‑system signoff is a negotiation between parties who each think their assumptions are obvious.

There's a pattern that shows up repeatedly. A team building an integration between a subscription platform and an accounting system does a great job on the happy path. Customer subscribes, invoice generates, money moves, everyone claps. The design review covers what the user sees. The engineering review covers whether the code runs. Nobody owns the space between the systems — the schema, the failure modes, the timing.

  1. The accounting side expects amount in cents. The subscription side sends dollars with two decimals. Nobody wrote it down. It "worked" in testing because someone happened to test with $10.00.
  2. One system treats a failed webhook as "retry silently." The other treats a missing event as "assume success." A payment fails, gets retried, and now there are two invoices.
  3. Design signed off on the cancellation flow. Engineering signed off on the cancellation flow. But cancellation involves a third system — the fulfillment queue — and no one from that team was in either review.

The reason this keeps happening is structural, not personal. Design signoff answers does this look and behave right for the user? Engineering signoff answers does this code do what the ticket says? Neither question covers the contract between systems. That contract is invisible, and invisible things don't get reviewed.

What an integration contract actually contains

An integration contract is just the written agreement about how systems talk to each other under normal and abnormal conditions. It's not a 40‑page document. The good ones fit on two pages and cover four things: data schemas, rollback behavior, SLA expectations, and ownership.

Most contracts fail by skipping one of these entirely — usually rollback.

1. Data schemas (the part people half‑do)

Everyone writes down field names. Almost nobody writes down:

  1. Units and formats. Cents vs dollars. ISO 8601 vs Unix timestamps. Is phone E.164 or freeform?
  2. Nullability. Which fields can be missing, and what does missing mean? A null discount and a discount of 0 are not the same thing to a billing system.
  3. Enums with a closed list. status can be one of active | paused | cancelled | past_due. If a fifth value ever appears, the receiving system must fail loudly, not guess.

The most common mistake: teams document the schema for the request and forget the schema for the event. The webhook that fires later is where the real disagreements live.

2. Rollback and failure behavior (the part people skip)

This section separates a real contract from a wish list. You have to define what happens when the integration is halfway done and something breaks.

  1. Is the operation idempotent? If the same event arrives twice, does the second one get ignored or duplicated?
  2. What's the retry policy — how many times, over what window, and does the sender back off?
  3. When a step fails, do you roll back the earlier steps or leave them in place and flag for reconciliation?
  4. Who gets notified, and where does the failed record land so a human can find it?

A common example: a scheduling system books an appointment, then calls a payment hold. The hold fails. Without a defined rollback, you've got a confirmed appointment with no payment attached — and the customer already got a confirmation email. Now someone in ops is manually hunting for orphaned bookings every Monday.

3. SLA expectations between systems

Not customer SLAs. System‑to‑system SLAs. How fast must System B acknowledge an event from System A? What's the acceptable lag before "slow" becomes "broken"?

Contract elementWeak versionContract‑grade version
Schema"sends order data"field list with units, nullability, closed enums, and event schema separate from request schema
Rollback"handles errors"idempotency key defined, 3 retries over 15 min, failed records routed to a named queue with an owner
SLA"should be fast"event acknowledged within 5s; reconciliation job runs hourly; alert if lag exceeds 2 min
Ownership(implied)named owner per system, plus one named owner for the contract itself

That last row matters more than it looks. Integrations fail in the seams, and seams have no natural owner. Someone has to own the contract, not just the endpoints.

A lightweight signoff ritual that survives real teams

Heavy signoff processes get abandoned because nobody has 90 minutes for a ceremony every time two systems touch. The ritual has to be short enough to run in 30 minutes and specific enough that skipping it feels genuinely risky.

Here's the version that actually sticks:

  1. Assemble the right room, not the whole room. One person per involved system, plus the design owner and the contract owner. If three systems are involved, you need a body from all three. The classic failure mode is the fulfillment team not being in the room when the cancellation flow gets signed off.
  2. Walk the contract, not the design. The demo already happened. This meeting is about the two‑page contract. Read the schema out loud. Yes, out loud — it's remarkable how many "obvious" disagreements surface when someone says "amount, in cents" and another person goes "wait, cents?"
  3. Run the three failure scenarios. Pick the three most likely break points and ask each system owner what their side does. Duplicate event. Failed downstream call. Malformed payload. If any answer is "hmm, not sure," that's an open item, not a signoff.
  4. Confirm rollback ownership. For each failure mode, name the queue, the alert, and the human. "Failed payment holds go to the payment_reconcile queue, alerts to #ops, owned by Dana."
  5. Sign with names and a date. Each system owner literally puts their name on the contract. This isn't bureaucracy — it's the moment where "I assumed you handled that" becomes impossible to say later.

Visualize the short signoff workflow below.

Process diagram

The whole thing takes 25–40 minutes if the contract was written beforehand. If it drags past an hour, that's usually a sign the contract wasn't real and you just discovered that in the room — which is still a win, because you found it before production did.

This pairs naturally with the review discipline in a rollout‑ready acceptance criteria template; the difference is that acceptance criteria describe what good looks like for the user, while the integration contract describes what good looks like between the machines.

The acceptance criteria that make signoff testable

Signoff means nothing if you can't verify it later. The contract needs acceptance criteria written as things you can actually check, not adjectives.

Bad: "The integration should handle errors gracefully."

Good, as a checklist:

  1. [ ] Sending the same event twice results in exactly one record (idempotency verified)
  2. [ ] A malformed payload is rejected with a logged error, not silently dropped
  3. [ ] A failed downstream call routes the record to the reconciliation queue within 2 minutes
  4. [ ] All enum values outside the agreed list trigger a loud failure, not a default
  5. [ ] Timestamps in both systems match to the second after a full round‑trip
  6. [ ] A cancellation propagates to all three systems, verified in each

Each of these is a test someone can run. That's the point. If a criterion can't be turned into a pass/fail check, it isn't acceptance criteria — it's a hope.

A real scenario

A mid‑sized e‑commerce operation — somewhere around 4,000 orders a month — was connecting their order system, a third‑party fulfillment provider, and their accounting software. The initial launch demoed perfectly. Everyone signed off on what they could see.

Within the first three weeks, reconciliation started drifting. Refunds issued in the order system weren't consistently reversing in accounting, because the two systems disagreed on whether a refund was a new negative event or a modification of the original. Nobody had written it down. Ops was spending 6–8 hours a week manually matching refund records, and finance flagged a mismatch of several thousand dollars at month‑end close.

When they went back and built an actual integration contract — closed enums for order status, an explicit refund event schema, a defined reconciliation queue with an owner, and a 30‑minute signoff where all three system owners walked the contract line by line — the drift essentially stopped. The manual matching dropped to occasional spot‑checks. The fix wasn't more engineering. It was agreeing, in writing, on the boundary that had been invisible the whole time.

When this makes sense — and when it's overkill

You don't need a formal integration contract for everything, and pretending you do is how teams learn to ignore the process.

This makes sense when:

  1. Three or more systems participate in a single business event
  2. Money, inventory, or legal records move between systems
  3. Failure in one system can create a silent inconsistency in another
  4. Different teams (or vendors) own the different systems

This is overkill when:

  1. It's one system with an internal function call
  2. The integration is read‑only and non‑critical (pulling display data)
  3. You control both ends and can deploy them together atomically

Who should NOT skip this: anyone integrating with a third‑party vendor. When you don't control the other side's code, the contract is the only thing protecting you from their assumptions changing without notice.

Where tooling quietly helps

None of this requires special software — a shared doc and a recurring calendar hold will get you most of the way. But once you're running these signoffs regularly across multiple integrations, the friction shows up in keeping contracts, ownership records, and open failure items from scattering across docs, chat threads, and someone's inbox.

That's the practical case for keeping everything in one operational workspace: the contract, the named owners, the open items from the last signoff, and the reconciliation queue's owner all in the same place instead of five. AI‑assisted operational tools can help here by flagging when a contract has no named owner, nudging when an open failure item has been sitting unresolved, and keeping a searchable trail of which version of the schema was signed off when. It's not magic — it's removing the "wait, where did we write that down" problem that quietly kills otherwise good processes.

Keep the contract, named owners, and open failure items in a single operational workspace to avoid lost context and duplication.

The tooling is secondary, though. The real work is deciding that the space between your systems deserves its own review — and giving it a contract, an owner, and 30 honest minutes before anything ships.

Closing thought

The demo will always look fine. That's exactly why demos are a bad place to sign off on a multi‑system integration. The disagreements that matter — units, nullability, retries, rollback, who owns the seam — are invisible on screen and only surface when money or inventory has already moved the wrong way. Write the two‑page contract, put every system owner's name on it, and walk it out loud for half an hour. It feels almost too simple for how much rework it prevents, and that's usually the sign you've found the right process rather than the elaborate one.

Built for Teams Tailored for collaborative workflows and dynamic project needs
Save Time Automate task assignments and streamline communication
Boost Productivity Optimize resource use and track progress effortlessly
Deliver Results Meet deadlines consistently and exceed team goals