Writing an Integration Requirement Without Designing the API

An integration requirement names the fact that crosses, the event, the owner and the failure. Eight crossings in one case, and the design words to strike.

Numbers in this note carry source tags ([POLICY], [THREADS n=10], [MINE]). What the tags mean.

This piece stands on the returns case published on this site: damaged-delivery refunds at a mid-size online retailer, built only from public sources - a published returns policy, help centre articles, ten public complaint threads I selected myself, consumer law and a walk through the published customer journey. No client, no interviews, and no access to any of the retailer's systems, so no system in this piece has a name. The case has five requirements with fifteen acceptance criteria. Below, every line where a fact leaves one system for another goes into one ledger, and the slots, the counts and the verdicts are mine [MINE].

An integration requirement states which business fact must pass from one system to another, on which event, which side's version of it counts, by when it must be usable, what the business does when it fails to arrive or arrives twice, and what must never cross. Endpoints, payload formats, field names, protocols and retry counts are not in it. Those belong to the people who build the interface.

In short

  • Six slots make an integration requirement: the fact, the trigger, the authoritative side, the deadline, the failure and the prohibition. None of them needs a word of API vocabulary.
  • The returns case has eight crossings. The one where money moves, from the refund decision to the payment side, has the most empty slots: three of six.
  • The case already contains a model integration sentence: REQ-015 criterion 3 handles duplicate and suppressed messages in business words, with no design word in it.
  • A struck design word is not deleted work. Each hides a business question, and the strike table turns six back into questions.

What is an integration requirement, if it is not an API spec?

Wikipedia's article on the interface control document defines it as "a technical document used to record, define and control interface information between systems, subsystems, equipment, hardware components or software components." That is the build team's document, where endpoints and error codes live.

The analyst's document sits one step earlier: what the interface must carry and what the business does when it misbehaves. The build team should be able to read it and design freely, the way the worked REQ-014 in the requirements template handles a screen: its "Mechanism note (suggestion, not a constraint)" holds the design idea in a line that is explicitly not a requirement.

The test for every sentence: could two teams design two different interfaces, a nightly file and a live call, and both satisfy it? If yes, the sentence is a requirement. If only one design satisfies it, it is a design decision, and it either moves to a mechanism note or gets a reason.

The crossing ledger: every place a fact leaves one system

Eight crossings, taken from the to-be in section 3.3 of the case, the five requirements and the scope tables. Quoted text is from the case. "Not written" means no requirement, rule or open question in the case fills the slot.

# Crossing Fact Trigger Whose version counts By when If it fails Must not
X1 Order record to pre-check (3.3) "order value and delivery date" Form submitted Not written Not written Passed to a person (REQ-018/2) Refuse (REQ-018/2)
X2 Form to case record (REQ-014/2) The submission timestamp Form submitted The form's, "not the moment an agent opens it" It is the clock Not written Re-stamp on receipt (RL-02)
X3 Decision to payment side (3.3, 3.4) Refund amount for the order Decision recorded Not written Issued "same working day"; payout window unchanged Not written Not written
X4 Duty rota to case (REQ-015/1-2) A named individual and a due date Breach of the 48 hour window Rota owner not named (OQ-04) "On breach" Weekend gap, fallback in OQ-04 "a shared mailbox, a group or a queue"
X5 Case to customer (REQ-015/3) Who holds the case, and by when Assignment, reassignment - Not written Not written A message on reopen
X6 Goods-in to Customer Care (REQ-017) Stated reasons and a dock photograph Item received does not match The goods-in lead's Within five working days of receipt Not written Reverse money automatically
X7 Pre-check to a person (REQ-018/2) The case and the reason it stopped Pre-check does not approve - Not written - Refuse; an error code
X8 Refund to accounting posting (1.5, 3.4) The posting Refund Finance systems As today As today Change: "Untouched"

Count the "Not written" cells per column. The fact and the trigger are written for all eight. The prohibition is written for seven, the strongest habit in the case. The deadline is missing for three (X1, X5, X7) and the failure for four (X2, X3, X5, X6).

The crossings that touch a person (X4 to X7) are written better than the ones between systems only (X1 to X3), which is where an integration review would start.

Why is the crossing where money moves the emptiest?

X3 is the only crossing where a mistake costs money directly, and the case leaves three of its six slots empty: whose version counts, the failure and the prohibition.

Section 3.4 explains why. The payout window is "a payment operation, not a decision", and the accounting posting stays "Untouched, which keeps Finance systems out of the release." Good scope decisions, and neither says what crosses back. The context diagram piece on this site reached the same gap from the scope end, marking the confirmation flow from payment as an inference: "The case reads as refunded on one side and as nothing on the customer's, and nobody watches the gap."

Then duplicates. The Enterprise Integration Patterns catalogue states the problem on its Idempotent Receiver page: "Even when a sender application only sends a message once, the receiver application may receive the message more than once." For a refund instruction that is a double payment. The pattern is the build team's choice. The business sentence underneath it is not written in the case: one recorded decision produces at most one payout.

X3 also hides a verb. The gap analysis piece found that "issued" names two events in the case: the refund triggered in the to-be, money reaching the customer in the as-is. At this crossing they split. Triggered belongs to the decision side, paid to the payment side, and nothing in the case says paid ever travels back.

Which crossing does the case already write well?

X5. REQ-015 criterion 3 in full: "The customer receives one message naming the person holding the case and the date by which they will hear back. A reassignment sends one further message. A case reopened by the customer sends none, because a reopen is not an escalation."

Three sentences settle what a build team would otherwise settle by accident: how many messages one event produces, which event adds one, and which produces none, with the reason. That is duplicate handling written as business. No email, no push, no queue. Any design can meet it, and any design can fail it.

X7 shows the same habit in miniature. REQ-018 criterion 2 wants the reason "phrased in the words of the rule that stopped it rather than an error code": the case struck a design word itself, once.

Is the goods-in reopen an event or a command?

Martin Fowler's article What do you mean by "Event-Driven"? describes event notification as a system telling others about "a change in its domain", where "the source system doesn't really care much about the response." It also names a trap: "an event is used as a passive-aggressive command", when "the source system expects the recipient to carry out an action" but sends the message as an event.

For X6 that distinction is a business decision, not a protocol choice. The goods-in lead reports a mismatch: who must act, and how? REQ-017 answers both. The reopened case "goes to a named owner in Customer Care with the same 48 hour clock as any other case", and "Money already paid is never reversed automatically."

So the reopen is a command to one party, a person in Customer Care, and must not become a command to another, the payment side. The case gives the reason: "Automatic clawback is the obvious design and it is the one that produces the complaint thread." Publish "item mismatch" as an event any system may act on, and clawback becomes something a developer can add later without touching a requirement. Written as a prohibition, it cannot arrive quietly.

The open slot on X6 is the anchor. "Within five working days of receipt" needs receipt to be recorded somewhere both sides can read. The BPMN piece reached this from the process side: "'Item received' becomes an event the process must catch, or the timer has no anchor".

Which timestamp crosses?

X2 is the crossing the case fixed under review. RL-02, the developer's "Under 48 hours from what moment?", exposed two readings: "One counts from the moment the customer presses submit. The other counts from the moment the case is received on our side."

That is an integration finding in plain words: two timestamps for one event, and the requirement must say which one travels. REQ-014 criterion 2 now does. The empty slot is the failure: a case that arrives without a form timestamp has no clock, and nothing says what happens then. The time zone question from the BPMN piece belongs in the same slot.

The design-word strike

Here is X3 written in API vocabulary. The draft is mine, invented for the exercise, not from the case.

On approval, the case service sends a POST to /refunds with order_id, amount and rule_version as JSON. On a 5xx response it retries three times with exponential backoff. Payment status comes back by webhook.

Every phrase might be right, and none is the analyst's to decide. Strike each one and ask what business question it stood on.

Struck The business question underneath Where the case answers it
POST /refunds, JSON Which facts must reach the payment side: the order, the amount, the decision behind it Amount rules in REQ-014/3 and BR-11; rule version in REQ-018/3
amount Does the order value tested against 40 EUR include delivery? Not stated, raised in the decision tables piece
retries three times What does the business do when payment does not confirm, and who hears about it? Not written
(no idempotency key) Is one decision paid at most once, however often the instruction is sent? Not written
webhook Which payment outcome must the case learn about, and how soon? Not written
case service Which system holds the decision record Deliberately not named. The case has no access to any system

Six struck phrases, six questions, and four of them have no answer anywhere in the case. The draft looked more finished than the case and was hiding more.

The integration requirement card, filled in

One card per crossing. This is X3, filled from the case's lines, with the empty slots carried as open items rather than invented.

Slot Value
Crossing Refund decision to the payment side
Fact that crosses The order, the refund amount (full, or partial only above 40 EUR order value, BR-11), and the decision it executes
Trigger A refund decision recorded by a person, or by the pre-check under REQ-018/1
Whose version counts The decision record. Not named in the case [OPEN]
By when Triggered the same working day (3.3). Payout window unchanged at 2 to 5 working days [POLICY]
If it fails to arrive Not written. Question routed to the e-commerce product owner, row 5 of the stakeholder map, my routing [MINE]
If it arrives twice Not written. Proposed: one recorded decision produces at most one payout [MINE]
What comes back Not written. Proposed: the case learns that the refund was paid or failed [MINE]
Must not cross Not written. Proposed: no change to the accounting posting, per 3.4 [MINE]
Mechanism note Any interface that meets the slots above. Suggestion, not a constraint
Source lines 3.3, 3.4, REQ-014/3, REQ-018/1, BR-11, stakeholder map row 5

Four rows are proposals marked as mine, each now arguable on its own line. Before the card, the crossing was three filled slots and an arrow.

The integration requirement card, blank

Slot Value
Crossing [From which system or party, to which]
Fact that crosses [The business fact, in the words of the rule that needs it. No field names]
Trigger [The recorded event that makes it cross]
Whose version counts [When two systems hold the fact, which one wins, and who owns that answer]
By when [How soon it must be usable, on a named clock]
If it fails to arrive [What the business does, and who hears about it]
If it arrives twice [Once, at most once, or harmless. Say which]
What comes back [Any outcome the sender must learn about, or "nothing"]
Must not cross [The action this crossing must never trigger]
Mechanism note [Design ideas, explicitly not constraints, or a dash]
Source lines [Requirement, rule and observation ids]

Where does this method stop?

It writes what the business needs from an interface, not whether the systems can deliver it or how much data crosses. Every "by when" slot here is a business clock, not a measured latency.

It also stops at the systems it can see. Carrier claims, which section 1.5 names as the owner of lost parcels, and the queue export behind OQ-06 are crossings this ledger cannot fill from outside.

The requirements template with its mechanism note is at /templates/requirements-register, the full case at /case, and the tags on the method page. Checks 01, 02 and 13 of the scorecard apply to every slot: trace to a rule, testable without the author, a start event for every clock.

Read next

All field notes · The portfolio guide · More in Requirements That Survive Review