04
Integrations
Make the systems you already own talk to each other, without rebuilding them
An integration doesn't fail when the vendor answers "error". It fails when it answers "fine" and does nothing, or when it sends the same order twice. That is where we start.
- InventoryWhat each system exposes and — above all — what it does not
- ContractData schema and error cases agreed before any code is written
- BridgeThe translation between the two models lives in one place, not scattered
- RepeatabilityEvery operation can be redone without harm: sooner or later it will be
- Safety netA periodic check realigns state when the other side goes quiet
- AlertingIf the link breaks we find out, not your customer
The contract comes first
Every exchange declares a schema: what comes in is checked before it touches anything, what goes out is documented. The payoff shows up on integration day: instead of discovering fields by trial and error, there is a document stating what arrives and what comes back — and a test that fails when someone changes it.
Duplicates, retries and a safety net
Messages arrive twice, out of order, or never. Every state-changing operation is written so it can be repeated without harm, and every queue has a retry ceiling with growing backoff.
When a vendor's connection proves unreliable you don't beg it: you put a periodic check beside it that realigns state. It costs little and removes a whole class of phone calls.
Systems that don't want to talk
Business systems with interfaces from the 2000s, platforms exposing a slice of what you need, public administration portals that accept a file and nothing else: the work is a layer that normalises all of it into one model, and keeps each vendor's quirks in a single place.
Which system owns each piece of data
Before a line is written we decide, for every piece of information, which system is the source of truth: stock is owned by the business system, orders are born in the online shop, the customer record belongs to whoever saw them first. There is no universally right answer — there is the right one for how you work, and it must be written down.
When that decision isn't taken, the integration takes it for you: last writer wins, and six months later nobody can explain why a price changed.
When the other side goes quiet
A link doesn't fail when the vendor returns an error: it fails when it answers "fine" and does nothing, or when the same order arrives twice because the confirmation was lost on the way.
So every state-changing operation is written to be repeatable without harm, every queue has a retry ceiling with growing backoff, and when the retries run out the thing doesn't die quietly: someone is told.
And when a vendor's link proves unreliable, you don't beg it: you put a periodic check beside it that realigns state. It costs little and removes a whole class of phone calls.
Old systems, government portals, files
Not everything exposes modern interfaces, and that is fine: you work with what exists. Scheduled exports, watched folders, files dropped on a server, sometimes read-only access to the database.
These are less elegant routes and perfectly workable, provided the same discipline applies: a declared format, a check on what comes in, and an alert when last night's file didn't arrive. The whole difference between an integration and a script lies there.
What we connect systems with
The technology matters less than the properties: repeatable, watched, with a written contract. These are the tools we use to get them.
Contracts
- OpenAPI
- Zod
- JSON Schema
- interface versioning
What comes in is checked before touching anything, and what goes out is documented. Changing a field becomes a deliberate decision instead of a surprise for the other side.
Transport
- REST
- webhooks
- PostgreSQL queues
- n8n
- files and watched folders
We pick the simplest medium that holds the case. A queue with exclusive claims stops two workers doing the same thing; for old systems, a watched folder is worth as much as a modern interface.
Reliability
- repeatable operations
- retries with backoff
- periodic reconciliation
- a record of every exchange
These four properties separate a bridge from a script. Reconciliation in particular is what saves you when the vendor has a problem and doesn't tell you.
Monitoring
- alerts on stalled flows
- exchange dashboard
- notifications by Telegram or email
- error log
An integration that stops silently is worse than none: nobody re-keys by hand any more and nobody knows the flow has stopped. The alert must reach a person, not a log nobody reads.
Portfolio
What we did on this, project by project.
Manora
API of a blockchain platform
- Documented APIs with input validation, rate limits and metrics exposed for monitoring.
- A separate process follows the chain block by block, rebuilds transactions and balances in PostgreSQL and resumes from where it stopped.
- Multilingual notifications to the app, generated from chain events rather than from the write path.
- Node.js
- PostgreSQL
- Redis
- OpenAPI
- Prometheus
BigFishIta
Public APIs and LinkedIn integration
- Read-only APIs for content and company profile with a per-company key: external automations read without the database being opened.
- Integration with the social publishing platform: inbound messages handled across the two payload shapes the vendor alternates, plus a five-minute check that realigns status and comments when the connection goes quiet.
- A job queue in PostgreSQL with exclusive claims and retries, drained on a schedule and right after each insert.
- Next.js
- PostgreSQL
- webhooks
- cron
CocoonServer
Management console for Odoo instances
- Every route behind a single typed authorisation check: authentication is never rewritten by hand per endpoint, so it cannot be forgotten.
- Long operations streamed to the browser as they happen, instead of a request that times out in silence.
- Next.js
- Prisma
- Kubernetes API
- SSE
Need this?
Tell us the problem and we'll tell you how we would tackle it — and if it isn't worth doing, we'll tell you that too.
Let's talk