The API Worked. So Why Did the Integration Still Fail?
A successful API response is not the same as a successful business process. Reliable integration depends on retries, idempotency, reconciliation, state, monitoring and recovery.
Rigg Technologies
Engineering Team
TL;DR
Reliable integration is not about getting two APIs to talk once. It is about making sure both systems remain consistent after retries, timeouts, duplicates, partial failures, outages and version changes — with reconciliation, auditability and recovery built in.
1. An API call is not an integration
System A sent the request. System B returned HTTP 200 OK. Everybody went
home happy.
Three weeks later, Finance discovered that 417 transactions were missing. System A said, “We sent everything.” System B said, “Our API is working.” Both teams were technically correct. The integration was still broken.
An API gives applications a way to communicate. A real integration has to ensure the business process actually completes.
The endpoint can be healthy while the business process is not.
Reliable integration is about state, recovery, consistency and traceability across both systems — not merely whether an HTTP request succeeded.
2. Start with the worst possible timing
Imagine an ERP asking a payment gateway to charge a customer. The gateway succeeds, but the response is lost on the network.
The customer has been charged. The ERP does not know it.
flowchart LR
E["ERP · Create Payment"] --> G["Payment Gateway"]
G --> C["Charge Customer"]
C --> S["SUCCESS"]
S -. "response lost" .-> X["ERP never receives result"]
classDef default fill:#fff,stroke:#d9d9d9,color:#111,stroke-width:1px;
classDef dark fill:#111,stroke:#111,color:#fff;
class S dark;
Retry blindly and you may charge twice. Never retry and the ERP may permanently think the payment failed. that is integration design.
3. “Success” has several meanings
Request sent? ✓
Remote server received it? ✓
Remote processing succeeded? ✓
Local system recorded result? ?
Both systems agree now? ?
A network request can succeed while the business transaction fails. A business transaction can succeed while the network request appears to fail.
4. HTTP status codes are not business truth
A 200 OK response might only mean “your request was accepted into a queue.”
The business
record may not exist yet.
flowchart LR
A["Send Request"] --> B["Request Accepted"] --> C["Queued"] --> D["Validated"] --> E["Processed"] --> F["Business Record Created"]
classDef default fill:#fff,stroke:#d9d9d9,color:#111,stroke-width:1px;
classDef dark fill:#111,stroke:#111,color:#fff;
class B dark;
5. The most dangerous error is sometimes no error at all
10,421 transactions
10,417 transactions
No exception. No outage. Just four missing records. Silent inconsistency is often more dangerous than a visible failure.
6. This is why reconciliation exists
Reconciliation asks a very simple question: Do both sides agree?
TX-98131
System A:
SUCCESS
System B:
MISSING
A mismatch should become visible and actionable.
Compare transaction IDs, amounts, timestamps and statuses so missing or conflicting records surface before Finance, Operations or a customer discovers them manually.
7. Retries without idempotency create duplicate business effects
If an order request times out, System A may correctly retry. If System B executes both requests, the customer gets two orders.
%%{init: {
'flowchart': {
'nodeSpacing': 15,
'rankSpacing': 20,
'padding': 6,
'useMaxWidth': false
}
}}%%
flowchart LR
A["REQ-918281"] --> Q{"Seen?"}
Q -->|No| C["Create Order"]
Q -->|Yes| R["Return Cached"]
classDef default fill:#fff,stroke:#d9d9d9,color:#111,stroke-width:1px,rx:6,ry:6;
classDef dark fill:#111,stroke:#111,color:#fff,stroke-width:1px,rx:6,ry:6;
class C dark;
First call:
create_order(request_id = REQ-918281)
→ CREATED
Retry:
create_order(request_id = REQ-918281)
→ ALREADY_PROCESSED
8. Retry the right failures, not every failure
%%{init: {
'flowchart': {
'nodeSpacing': 15,
'rankSpacing': 20,
'padding': 6,
'useMaxWidth': false
}
}}%%
flowchart LR
E["Integration Error"] --> Q{"Type?"}
Q -->|TIMEOUT| R["Retry"]
Q -->|RATE_LIMIT| L["Retry later"]
Q -->|503| S["Retry"]
Q -->|INVALID_REQUEST| N["Do not retry"]
Q -->|UNAUTHORIZED| A["Stop + alert"]
Q -->|NOT_FOUND| B["Business handling"]
classDef default fill:#fff,stroke:#d9d9d9,color:#111,stroke-width:1px,rx:6,ry:6;
classDef dark fill:#111,stroke:#111,color:#fff,stroke-width:1px,rx:6,ry:6;
class A dark;
If every error enters the same retry loop, you have not built resilience. You have built persistence.
9. Failed records need somewhere to go
Retry forever is not reliability. Eventually, unrecoverable records need a visible manual recovery path.
%%{init: {
'flowchart': {
'nodeSpacing': 15,
'rankSpacing': 20,
'padding': 6,
'useMaxWidth': false
}
}}%%
flowchart LR
Q["Normal Queue"] --> P["Process"] --> R1["Retry"] --> R2["Retry"] --> F["Still Failed"] --> D["Dead Letter Queue"]
classDef default fill:#fff,stroke:#d9d9d9,color:#111,stroke-width:1px,rx:6,ry:6;
classDef dark fill:#111,stroke:#111,color:#fff,stroke-width:1px,rx:6,ry:6;
class D dark;
10. Systems also disagree about identity
ERP customer 10082, CRM customer CUS-88231 and payment customer
P-9210 may all represent the same business.
That relationship needs an explicit mapping. Display names are not reliable identifiers.
ERP Customer:
10082
CRM Customer:
CUS-88231
Payment Customer:
P-9210
11. Event order can break otherwise-correct integrations
Expected:
1. Customer Created
2. Customer Updated
Received:
2. Customer Updated
1. Customer Created
Distributed systems do not always deliver events in the order you expect. That must be part of the design.
12. Partial failure is normal
Suppose an order transfer creates the customer and the order, then fails while reserving stock. “Integration failed” is too vague. Some of it already succeeded.
flowchart LR
A["NEW"] --> B["CUSTOMER_SYNCED"] --> C["ORDER_CREATED"] --> D["STOCK_RESERVED"] --> E["DELIVERY_CREATED"] --> F["COMPLETED"]
C -. failure .-> X["STOCK_RESERVATION_FAILED"]
classDef default fill:#fff,stroke:#d9d9d9,color:#111,stroke-width:1px;
classDef dark fill:#111,stroke:#111,color:#fff;
class X dark;
13. Logs should explain the business flow
Integration Run:
INT-82910
Source:
ERP
Destination:
Warehouse System
Record:
ORD-10021
12:01:02 Order received
12:01:04 Customer mapped
12:01:05 Order created remotely
12:01:06 Stock reservation failed
Reason:
SKU-1182 not found
Status:
ACTION_REQUIRED
POST /orders returned 200 helps a developer. The trail above helps somebody
actually solve
the business problem.
14. Monitoring uptime is not enough
An API can be 99.99% available while 1,208 transactions are stuck in a retry queue.
System uptime is a technical metric. Transaction health is a business metric.
15. Eventual consistency is not necessarily a bug
If an order appears in reporting eight seconds after creation, that may be perfectly acceptable. The important part is defining the expected behavior.
Expected delay:
< 30 seconds
Alert if:
Delay > 5 minutes
16. Integrations need clear data ownership
If ERP and CRM both believe they own the customer phone number, they can end up synchronizing the same field back and forth forever.
CRM owns
ERP owns
Accounting owns
Other systems consume; they do not independently redefine the source of truth.
17. Validate data and restrict integration access
A weak integration says, “If System A sent it, insert it.” A stronger one validates amount, currency, customer identity, dates and required fields.
Integration credentials should also follow least privilege, expiry, rotation, encryption, scoped access and audit logging.
REJECTED
Reason:
CUSTOMER_NOT_FOUND
18. API contracts change eventually
Today:
{
"customerName": "ABC Ltd"
}
Tomorrow:
{
"customer": {
"name": "ABC Ltd"
}
}
Reliable integrations need versioning and compatibility planning because fields, enums, validation rules and schemas change over time.
19. Good integration architecture expects failure
The goal is not to make failure impossible. It is to make failure detectable, recoverable, traceable and safe.
%%{init: {
'flowchart': {
'nodeSpacing': 15,
'rankSpacing': 25,
'padding': 6,
'useMaxWidth': false
}
}}%%
flowchart TD
subgraph row1 [" "]
direction LR
S["Source System"] --> E["Create Event"] --> V["Validate"] --> Q["Queue"] --> N["Send"] --> R["Remote System"]
end
subgraph row2 [" "]
direction LR
X["Receive Result"] --> Y["Verify"] --> P["Persist State"] --> C["Reconcile"] --> D["Completed"]
end
R ==> X
classDef default fill:#fff,stroke:#d9d9d9,color:#111,stroke-width:1px,rx:6,ry:6;
classDef dark fill:#111,stroke:#111,color:#fff,stroke-width:1px,rx:6,ry:6;
style row1 fill:none,stroke:none;
style row2 fill:none,stroke:none;
class E,Q,C dark;
20. The two systems should be able to disagree safely
MISMATCH DETECTED
Transaction:
TX-10921
ERP:
PAID
Gateway:
UNPAID
Action:
REVIEW REQUIRED
A dangerous integration silently chooses one side. A safer system makes the disagreement visible.
21. A small reconciliation job can prevent a large business problem
Every night:
compare today's transactions
find missing records
find amount mismatches
find status mismatches
attempt safe recovery
report unresolved differences
This may never appear in a product demo. It may prevent months of accounting confusion.
22. What should you ask an integration vendor?
Ask how the integration behaves when things go wrong
- How do you handle retries?
- How do you prevent duplicates?
- How do you reconcile records?
- What happens during partial failure?
- How are failed records recovered?
- How do we monitor transaction health?
- How are IDs mapped?
- Where is the audit trail?
- How do you handle version changes?
23. APIs are the easy part
Writing http.post(...) is usually not the difficult part.
The difficult part is ensuring that after 100 requests, 10,000 requests, 10 million requests, network failures, server restarts, deployment changes and partner outages, both systems still agree about what happened.
That is integration engineering.
24. What this looks like from the business side
Missing or duplicate transactions create reconciliation work and financial risk.
Teams waste time comparing systems and manually repairing broken flows.
A payment can succeed while the order or account still shows the wrong state.
Healthy API uptime can hide unhealthy transaction processing unless business-level monitoring exists.
The real question is not whether System A can call System B.
It is whether both systems can keep behaving like one business process when networks fail, records disagree, retries happen, schemas change and one side goes offline.
25. Your APIs may already be working. Your integration may still need work.
At Rigg Technologies, we build integrations between internal applications, ERP systems, external services, mobile platforms, payment systems and other business software.
If your systems are connected but your teams still spend time comparing numbers, re-entering data, fixing duplicates or chasing missing transactions, the integration layer is probably where the real work remains.
26. FAQ
What technologies did you use?
We used Node.js, PostgreSQL, Redis, React, and AWS cloud infrastructure to build the complete solution.
How long did the implementation take?
The entire project took approximately 12 weeks from initial discovery to deployment.
How is the system secured?
Role-based access control, end-to-end data encryption, and continuous monitoring ensure high security standards.
Can it integrate with other tools and regions?
Yes, through flexible REST/GraphQL APIs and multi-tenant setup for global scale.
27. Comments & Testimonials
Priya Shah
3 days agoCOO
"Fantastic transformation! This platform is an absolute backbone for our operations."
Rohit Menon
5 days agoIT Head
"Real-time visibility has reduced firefighting significantly. Great work, team!"