March 1 2025
How to Design a Third-Party Integration Without Becoming a Hostage
How to integrate with an external vendor without spreading their contract through your whole system or turning every change on their side into your incident.
Andrews Ribeiro
Founder & Engineer
4 min Intermediate Systems
Track
Startup Engineer Interview Trail
Step 7 / 10
The problem
A third-party service usually enters the system with a simple promise:
- charge a payment
- validate a document
- send an email
- enrich some data
At first it looks like just another HTTP call.
Months later, the team realizes that half the flow now speaks the vendor’s language.
When that happens, any external change becomes an internal problem:
- a field changed
- a limit got tighter
- latency got worse
- a webhook was delayed
- a status came back differently
You are not a hostage because you depend on something.
You become a hostage when the dependency has no clear boundary.
Mental model
A third-party integration should answer this question:
how do I use this external capability without letting my system take on its shape?
That leads to four ideas:
- the vendor contract should stay contained
- vendor failure should not contaminate everything
- your domain should keep speaking its own language
- switching or changing vendors should not require a full rewrite
Breaking the problem down
Do not spread the vendor contract everywhere
Classic mistake:
- the third-party response comes in
- their names become your names
- their statuses become your business statuses
- their payload flows through several layers
When that happens, the system stops integrating and starts absorbing the vendor.
Better shape:
- one internal layer talks to the vendor
- it translates the external contract into your own model
- the rest of the system depends on the internal model
That only looks like bureaucracy until the first external change.
Treat the vendor like an unstable dependency
Even a good vendor can:
- get slow
- return a partial error
- reply out of order
- impose rate limits
- change behavior
So a mature integration usually has:
- timeout
- retry with criteria
- circuit breaker
- idempotency when the operation is sensitive
- observability for failures and latency
Not because the vendor is bad.
Because external dependency is, by nature, less controllable.
Your domain needs to keep being yours
If the vendor calls payment states one way and your business calls them another, do not copy them blindly.
Example:
- vendor:
authorized,captured,voided - your business:
awaiting_confirmation,paid,cancelled
Those can relate to each other, but they do not have to be the same mental table.
If you glue them together too early, your business rule starts obeying the vendor’s semantics by accident.
Fallback has to be honest
When the third party fails, the common options are:
- degrade the feature
- queue work for later
- show a clear error
- use cache where it actually makes sense
The important thing is not to invent fake success.
Bad example:
- payment vendor is down
- the system marks the order as paid “so UX does not get blocked”
That is not resilience.
That is delayed damage.
Simple example
Imagine a shipping provider integration.
Bad flow:
- the frontend calls your backend
- your backend calls the provider
- the provider’s response comes back almost raw into your domain
- several modules start depending on that provider’s names, errors, and statuses
If the provider changes a field or gets very slow, everything feels it.
Better flow:
- your backend calls an internal shipping adapter
- the adapter talks to the provider
- it translates response and error into an internal model
- your system understands
quote_available,quote_unavailable,retry_later
Now the vendor is still important.
But it no longer shapes the whole system.
Common mistakes
- Spreading external payload through the whole system.
- Trusting a vendor as if it were your own internal module.
- Not having a timeout and leaving requests hanging.
- Mapping business state directly to vendor status.
- Treating a vendor switch as impossible because the coupling is already total.
How a senior thinks
People with more experience look at a third-party service and think:
“I want to use its capability, not outsource my domain design to it.”
That sentence captures the goal well.
A healthy integration accepts dependency without handing over the keys to the house.
What the interviewer wants to see
In an interview, this topic usually comes up when they ask for an external integration design.
The evaluator wants to see whether you think in boundaries, risk, and evolution.
Good signs:
- you talk about an adapter layer
- you mention timeout, retry, and circuit breaker
- you separate vendor semantics from business semantics
- you talk about observability and fallback
A strong answer usually sounds like this:
“I would isolate the third-party contract behind an internal layer, with timeout, retry, and translation into my own model. That way I reduce coupling and handle vendor failure or vendor change more safely.”
A healthy integration uses a vendor as a dependency. A bad integration promotes the vendor to co-author of your system.
Quick summary
What to keep in your head
- A good third-party integration isolates the external contract instead of spreading the vendor's language through the whole system.
- Your system needs to stay understandable when the vendor fails, changes behavior, or limits traffic.
- Adapter, timeout, retry, circuit breaker, and observability matter more than optimism.
- The less your domain depends on the vendor's exact shape, the less of a hostage you become.
Practice checklist
Use this when you answer
- Can I explain why a third-party contract should live behind an internal layer?
- Do I know how to handle timeout, error, rate limit, and unavailability?
- Can I describe fallback or degradation without inventing dangerous behavior?
- Can I talk about switching vendors without imagining a full rewrite of the system?
You finished this article
Part of the track: Startup Engineer Interview Trail (7/10)
Share this page
Copy the link manually from the field below.