APIs and integrations that hold up under real traffic.
Two systems talking over an API is easy on the happy path. The work is everything else: the vendor that times out, the duplicate that arrives twice, the field that changed shape.
The happy path is not the job.
Most integration briefs are written as a list of endpoints. What they leave out is the failure model: what happens when the vendor is down for an hour, when the same order is posted twice, when a partner sends a field you have never seen. That is where integrations actually break.
So we start with the API contract and write it before the implementation. Resources, error shapes, pagination, auth, versioning policy — agreed on paper, so two teams can build against it at once and neither is guessing. JWT authentication, idempotency keys and retry queues follow from the contract, not from an incident.
The other half of this work is somebody else's API, which you do not control. Payments, accounting, communications, mapping and measurement vendors all behave differently under load and all change without asking. One adapter per vendor keeps their surprises in one file, and out of the rest of the system.
Every integration we add makes the next one harder.
One adapter per vendor, one internal shape they all map into. New vendors touch one file instead of spreading their field names through your codebase.
The vendor's API went down and took our checkout with it.
Timeouts, circuit breaking and a retry queue with backoff, so an outside failure becomes a delay rather than a page nobody can load.
We got billed twice for the same order.
Idempotency keys on every write that costs money, plus a request log you can query. The second identical call returns the first result instead of doing the work again.
Nobody can tell us what our own API promises.
A written API contract with examples, error codes and a versioning policy, published where your consumers can read it. Changes become deprecations instead of surprises.
Scope, spelled out.
Contract-first API design
Resources, error shapes, pagination and auth agreed in writing before implementation, so front end and back end can be built at the same time.
WebSocket and real-time
Live data where polling would be wasteful: presence, order books, chat and alerts. Reconnection and replay are handled, not hoped for.
JWT authentication
Token issue, refresh and revocation, scoped claims, and an auth story that survives a leaked token without logging out every customer.
Idempotency and retries
Idempotency keys on writes that move money, a retry queue with backoff, and dead-letter handling so a failed inbound webhook is visible rather than lost.
One adapter per vendor
Payments, accounting, communications, mapping and measurement tools, each behind a single adapter that maps their shape into yours.
Backend architecture
Queues, workers, caching and read paths sized to your traffic shape, with the cloud pieces chosen for what you can actually operate.
Docs and a sandbox
Published reference, runnable examples and a sandbox your consumers can hit, because an API nobody can try is an API nobody adopts.
What actually happens, week by week.
Contract first
We write the spec and the error shapes before the implementation, then get both sides to sign it.
Auth and errors
Token issue, refresh and scopes, plus one consistent error format every consumer can rely on.
Adapter per vendor
Each third-party integration behind its own boundary, mapping the vendor's shape into your internal one.
Harden the edges
Idempotency keys, a retry queue with backoff, timeouts and the load profile you actually expect.
Sandbox and docs
A published reference, runnable examples and a sandbox, handed to whoever consumes the API next.
The tools we actually use here.
REST where it fits, WebSocket where polling would be waste, and queues in front of anything a vendor can make slow. Everything below is something we've shipped, not a logo wall.
Deliverables, outcomes and who this is for.
- Written API contract and examples
- Auth model with scopes and refresh
- One adapter per vendor
- Idempotency and retry queue
- Published docs and a sandbox
- Load and failure test results
- Vendor outages become delays
- No duplicate charges on retries
- New integrations touch one file
- Consumers can self-serve the docs
Engineering leads connecting systems to each other or to a vendor's API, and teams publishing an API other people depend on.
Integrations that had to hold.
A multi-agency CRM for roofing companies
6+ live integrations, one boundary each
Hover for measurements, Beacon for live pricing and automated ordering, Twilio for messaging, Stripe for payments with refunds, QuickBooks for accounting, Google Calendar for scheduling. Each sat behind its own adapter, because Beacon pricing going quiet must not stop an invoice from being written.
Real-time, then reconciled
The trading platform used REST to place and manage orders and WebSocket for live balances and activity. The lesson was ordering: the socket feed is fast but not authoritative, so state was reconciled against the REST responses. Trusting the stream alone shows traders positions they do not have.
Questions we get on the first call.
Per integration when the vendor has documentation and a sandbox, per sprint when it doesn't. The first kind is predictable work we can quote. The second is archaeology against somebody else's undocumented behaviour, and a fixed price there is a guess with extra confidence. We'll tell you which one you have after reading their docs.
The adapter absorbs it and your code doesn't move. That's the whole reason for the boundary. We also add contract checks against the vendor's responses, so a changed field fails a test instead of failing a customer. Fixing the adapter is billable work, and it's an adapter fix rather than a refactor.
You do. Credentials live in your secret store and your vendor accounts, and we work through short-lived access you can revoke without asking us. If a vendor only issues one shared key, we say so, use it for the build, and rotate it at handover. Nothing lands in a repository or a chat thread.
Yes, and it's often the first useful thing to do. We read the routes, exercise them against a copy, and write the contract that should have existed: resources, error codes, auth, pagination. Expect the exercise to also produce a list of behaviours nobody intended. That list is usually the more valuable deliverable.
Carefully, and in writing. We build a recorded fake from their real responses, run the integration against that, and keep production calls to a small, reversible set until we trust it. We also agree with you beforehand which live actions are safe to test and who is on the call when we try them.
More in Custom Software & SaaS.
Design the contract before anyone writes a client.
Send the vendor docs, or the endpoint list somebody wrote in a ticket. We'll tell you where the failure model is missing before you commit a sprint to it.