Integrating Multiple Carrier APIs: A Survival Guide for Telecom-Adjacent Startups
Quick Answer: Telecom startups integrating multiple carrier APIs should normalize responses into a unified schema, implement circuit breakers for latency spikes, build tiered fallback chains (primary to secondary to cached), and monitor API health in real-time. These four practices prevent outages, reduce integration complexity by 60-70%, and keep your eSIM or MVNO platform reliable as you scale from two carriers to twenty.
Introduction
If you're building an eSIM platform, travel connectivity app, or MVNO service, you've probably stared at the abyss. On one side: your clean, product-focused API that customers love. On the other: a dozen carrier APIs that return data in wildly different formats, go down at 3 AM, and rate-limit you into submission.
We've been there. At iWanteSIM, we went from integrating two carriers to managing relationships with fourteen different operators across six continents. Each one had its own quirks, its own auth scheme, its own idea of what an error response should look like. Some returned XML. One sent SMS confirmations for every API call. Another required us to fax a certificate. Yes, in 2025.
This isn't a theoretical architecture post. It's a survival guide written from the trenches. We'll cover the three hardest problems we faced—API normalization, latency management, and fallback strategies—and the patterns that actually worked.
Why Carrier API Integration Breaks Most Startups
Most SaaS integrations are straightforward. You call Stripe for payments, Twilio for SMS, SendGrid for email. These APIs are well-documented, versioned predictably, and behave consistently across regions.
Carrier APIs are none of those things.
The telecommunications industry runs on standards that predate the internet. SS7, SIGTRAN, Diameter—these protocols power the networks we use daily, but they don't translate cleanly to REST or GraphQL. When carriers expose APIs for partners, they're often thin wrappers around legacy BSS/OSS systems built in the 1990s.
Common pain points we encountered:
- Inconsistent data models: One carrier returns IMSI as a string, another as a number, a third nests it three levels deep
- Undocumented rate limits: We hit a carrier that silently dropped requests after 10 TPS—with no Retry-After header
- Unpredictable downtime: Maintenance windows that aren't announced, or worse, announced 15 minutes after they start
- Authentication soup: OAuth 2.0, mutual TLS, API keys in headers, API keys in query params, HMAC signatures, and one that required a custom SOAP header
- Regional variations: The same carrier's European API returned JSON; their Asian API returned XML with different field names Without a deliberate strategy, these inconsistencies compound until your engineering team spends 80% of their time on integration plumbing instead of product features.
Pattern 1: API Normalization Layer
The first and most important pattern we implemented was a normalization layer—a dedicated service that sits between your application and all carrier APIs.
Here's what it does in practice:
Unified Request Schema
Your application sends standard requests like POST /activate-esim with a clean JSON body:
{
"customer_id": "cust_abc123",
"plan_code": "global_5gb_30d",
"region": "APAC",
"device_imei": "351234567890123"
}
The normalization layer translates this into whatever format Carrier A, B, or C expects. Maybe Carrier A wants a SOAP envelope. Carrier B wants a GraphQL mutation. Carrier C expects a multipart form with a PDF attachment. Your app doesn't care.
Unified Response Schema
Responses get normalized back to a standard format:
{
"status": "activated",
"carrier_ref": "carrier_789",
"iccid": "8901234567890123456",
"activated_at": "2025-08-25T14:32:00Z",
"expires_at": "2025-09-24T14:32:00Z"
}
Every carrier response gets mapped to this schema, regardless of whether the original was XML, JSON, or a CSV emailed to you 20 minutes later.
Why This Matters for Scale
When we added our seventh carrier, the integration took two days instead of two weeks. The normalization layer handled 90% of the translation. We only needed to write a new adapter that mapped the carrier's quirks to our standard schema.
Key insight: Your application should never know it's talking to multiple carriers. It should talk to one consistent API that happens to route to different backends.
Pattern 2: Latency Management and Circuit Breakers
Carrier APIs are slow. Not "add 50ms" slow. We're talking 2-8 seconds for basic operations, with occasional 30-second outliers that will destroy your response times if you let them.
What Is a Circuit Breaker?
A circuit breaker monitors API calls and "opens" when failure rates or latency exceed thresholds. Once open, requests fail fast instead of waiting on a broken dependency. After a cooldown period, it "half-opens" to test if the service recovered.
We use the opossum npm package (1.2M weekly downloads) for Node.js implementations. It takes about 20 lines of code to wrap a carrier client:
const CircuitBreaker = require('opossum');
const options = {
timeout: 5000, // 5s max wait
errorThresholdPercentage: 50,
resetTimeout: 30000 // 30s before retry
};
const breaker = new CircuitBreaker(carrierApiCall, options);
breaker.fire(args);
Latency Distribution Across Carriers
Here's what we measured across our carrier pool (p95 response times for an eSIM activation):
Carrier Regionp95 LatencyNotesNorth America1.2sConsistent, well-documentedWestern Europe2.8sOccasional 10s spikes during peakAPAC Tier 14.5sHigh variance, 1-15s rangeAPAC Tier 28.2sUnpredictable, needs aggressive timeoutsLatin America6.1sFrequent maintenance windowsWithout circuit breakers, a single slow carrier would cascade latency into your entire user experience. With them, you fail fast and route around the problem.
Async Processing for Non-Critical Paths
Not every carrier operation needs to be synchronous. We moved quota checks, usage reporting, and billing reconciliation to background queues using BullMQ. This cut our synchronous API latency by 40% and made the platform feel snappier even when carriers were sluggish.
Pattern 3: Tiered Fallback Strategies
When a carrier fails—and it will—you need a plan B. And usually a plan C.
Our Three-Tier Fallback Model
Tier 1: Primary Carrier
The customer's preferred or cheapest option. This handles 80% of traffic.
Tier 2: Secondary Carrier
A different network in the same region, activated automatically when Tier 1 fails. We maintain active contracts with 2-3 carriers per major region.
Tier 3: Cached/Cached-Only Mode
We cache activation profiles and basic metadata in Redis. If all live carriers are down, we can still display plan details, pricing, and even pre-provisioned eSIMs that were prepared during low-traffic hours.
Fallback in Practice
Here's a simplified version of our activation flow:
async function activateESIM(request) {
const primary = await tryCarrier(carriers.primary, request)
.catch(() => null);
if (primary) return primary;
const secondary = await tryCarrier(carriers.secondary, request)
.catch(() => null);
if (secondary) return secondary;
return cache.getPreprovisionedProfile(request.region);
}
The user gets their eSIM. They don't know there was a problem. Your support ticket volume stays low.
Pre-Provisioned eSIMs
Our most effective reliability hack: we pre-provision eSIMs during off-peak hours and store them in a pool. When a user requests activation, we assign a pre-warmed profile instead of calling a live carrier API. This turns a 5-second unpredictable API call into a 50ms database lookup.
We keep about 500 pre-provisioned profiles per region, replenishing the pool every hour. The cost is minimal compared to the reliability gain.
Monitoring: You Can't Fix What You Can't See
All these patterns depend on visibility. We built a carrier health dashboard that tracks:
- API success rate by carrier and endpoint
- p50/p95/p99 latency trends over time
- Circuit breaker state (closed/open/half-open)
- Fallback frequency—how often we hit Tier 2 or Tier 3
- Error classification—auth failures, timeouts, 5xx, rate limits We alert via PagerDuty when any carrier drops below 95% success rate for 5 minutes. More importantly, we review weekly trend reports to spot degradation before it becomes an outage.
One discovery from our monitoring: a carrier we thought was reliable had a 2% error rate that spiked to 15% every Tuesday at 02:00 UTC. Their database backup window. We shifted traffic away during that window and our activation success rate jumped from 97% to 99.7%.
What We Got Wrong (So You Don't Have To)
We've made plenty of mistakes. Here are the expensive ones:
1. Tight coupling to carrier-specific fields
Early on, we exposed raw carrier IDs and status codes directly to our frontend. When a carrier changed their status mapping, our UI displayed "active" as "suspended" for 6 hours. Embarrassing.
2. Not versioning our normalization layer
We updated our unified schema without versioning, breaking three downstream integrations. Now we version our internal API like a public product: /v1/activate, /v2/activate.
3. Ignoring idempotency
Carrier APIs aren't always idempotent. We double-charged customers when our retry logic fired on a timeout that actually succeeded. Now every activation request includes an idempotency key, and we track state transitions explicitly.
4. Assuming all OAuth 2.0 implementations are equal
One carrier returned the access token in a custom header. Another used a non-standard grant type. Always read the actual implementation, not the spec.
Key Takeaways
- Normalize everything: Build a translation layer so your application talks to one consistent API, not fifteen different ones
- Fail fast with circuit breakers: Set aggressive timeouts (3-5s for most carrier operations) and open circuits when latency or error rates spike
- Always have a fallback: Maintain secondary carrier relationships and pre-provisioned profiles for when primaries fail
- Monitor obsessively: Track latency percentiles, error classification, and fallback frequency by carrier and region
- Version your internal APIs: Your normalization layer is a product—treat it like one
- Cache aggressively: Pre-provisioned profiles and metadata caching turn unpredictable API calls into fast database lookups
- Plan for inconsistency: Carrier APIs will violate every assumption you have about REST conventions, authentication, and error handling
Frequently Asked Questions
How many carriers should a startup integrate initially?
Start with two carriers in your primary market. This gives you pricing leverage and a basic fallback option. Add a third when you expand regions, not before you've solidified your normalization layer and monitoring.
What's the average cost of maintaining a carrier integration?
Expect 20-40 hours of engineering time per carrier for initial integration, plus 5-10 hours monthly for maintenance, credential rotation, and API changes. A normalization layer cuts ongoing maintenance by 60-70%.
Should we use a carrier aggregator instead of direct integrations?
Aggregators like Airalo's B2B platform or Truphone reduce integration overhead but add cost (typically 15-30% margin) and limit flexibility. We recommend direct integrations for core markets and aggregators for long-tail regions.
How do you handle carrier API versioning?
We don't rely on carriers to version gracefully. Our normalization layer abstracts version changes, and we run parallel adapters during migration periods. We also subscribe to carrier developer newsletters and maintain direct Slack channels with their technical contacts.
What timeout values work best for carrier APIs?
We use 5 seconds for activations, 3 seconds for status checks, and 10 seconds for bulk operations. These are aggressive but force us to build fallback logic instead of accepting poor performance. Adjust based on your carrier's actual p95 latency.
How do you maintain carrier relationships?
Beyond contracts, designate a technical point of contact on both sides. Join their developer Slack or Discord if available. Send monthly usage reports proactively. Good relationships mean faster support when things break—and they will break.
What's the biggest mistake startups make with carrier APIs?
Treating carrier integrations like standard SaaS APIs. They're not. Expect inconsistency, poor documentation, and breaking changes. Build defensively: normalize responses, implement circuit breakers, and never assume a carrier API will behave the same way twice.
How do pre-provisioned eSIMs work legally?
Pre-provisioning means requesting eSIM profiles from carriers during off-peak hours and storing them in a pool. You still pay for each profile, but activation is instant for the user. Check your carrier agreement—some prohibit storing profiles beyond 24 hours.
What monitoring tools do you recommend?
We use DataDog for APM and custom dashboards, PagerDuty for alerting, and a custom carrier health score we calculate every minute. Open-source alternatives include Prometheus + Grafana for metrics and Alertmanager for paging.
When should we build our own normalization layer vs. using an open-source solution?
Build custom if carrier APIs are your core differentiator or if you need deep control over fallback logic. For MVPs, explore open-source telecom abstraction libraries, but be prepared to outgrow them—none we evaluated handled the full complexity of real carrier integrations.
Conclusion
Integrating multiple carrier APIs isn't glamorous work, but it's the foundation that everything else in your telecom product sits on. Get it wrong, and you'll spend your days firefighting outages and apologizing to customers. Get it right, and your platform becomes invisible—in the best possible way.
At iWanteSIM, we've learned that reliability isn't a feature you ship once. It's a practice you maintain daily through normalization, circuit breakers, tiered fallbacks, and obsessive monitoring.
If you're building in this space, start with the patterns that matter: one clean API abstraction, aggressive timeouts, and always—always—have a plan B.
We're sharing what we learn as we build. Follow along on our blog or explore our technical guides for more on eSIM architecture, carrier negotiations, and scaling connectivity platforms.
Top comments (0)