Third-Party API Integration Mistakes That Break Your Website
Every modern web application depends on third-party APIs. Payment processors, shipping carriers, email services, analytics platforms, CRM systems, and dozens of other external services are woven into the fabric of your application. When these integrations work, they are invisible. When they fail, they can take your entire website down with them. At Forth Media, we have inherited and rescued more projects than we can count where a single poorly implemented API integration was responsible for cascading failures, lost revenue, and frustrated customers.
This article catalogs the most common and most damaging API integration mistakes we encounter, along with the specific patterns and practices that prevent them. If your application relies on any third-party service, at least one of these mistakes is likely lurking in your codebase right now.
Mistake 1: No Error Handling
This is the most fundamental and the most common mistake. Developers write the happy path, verify that the API call works in their local environment, and ship it. There is no try-catch block, no response status check, no fallback behavior. When the API returns a 500 error, an unexpected response format, or simply times out, the application crashes.
The damage is proportional to where the API call sits in your application flow. An unhandled error in a product recommendation API is an inconvenience. An unhandled error in your payment processing API means customers cannot check out. An unhandled error in your authentication provider means nobody can log in.
Every API call in your application should be wrapped in error handling that accounts for at least these scenarios:
- HTTP errors including 4xx client errors and 5xx server errors. Each status code may require different handling. A 429 rate limit response should trigger a retry with backoff. A 401 unauthorized response should trigger a token refresh. A 503 service unavailable should activate your fallback logic.
- Network errors including DNS resolution failures, connection refused, connection reset, and SSL handshake failures. These are distinct from HTTP errors because no response is received at all.
- Malformed responses where the API returns a 200 status but the response body does not match the expected schema. Never assume that a successful status code means the response contains valid data.
- Timeouts where the API does not respond within your configured time limit. This is common enough to warrant its own category and its own handling logic.
Mistake 2: No Timeouts
If you do not explicitly set a timeout on your HTTP client, most libraries will wait indefinitely for a response. When a third-party API is experiencing latency issues, your application's threads or processes will pile up waiting, eventually exhausting your server's capacity and bringing down your entire site, not just the feature that depends on that API.
This is one of the most insidious failure modes because it is silent. There are no error messages, no exceptions, no alerts. Your application just gradually becomes unresponsive as more and more requests stack up waiting for a slow external service.
Set explicit timeouts on every external HTTP call. We recommend configuring two separate values:
- Connection timeout limits how long the client will wait to establish a TCP connection. This should be short, typically two to five seconds. If you cannot connect to the API server within this window, it is likely down.
- Response timeout limits how long the client will wait for the complete response after the connection is established. This should be based on the expected response time for that specific API, typically five to thirty seconds depending on the operation.
For user-facing requests where perceived performance matters, consider even shorter timeouts with aggressive fallback behavior. If your product recommendation API does not respond within one second, show bestsellers instead of making the customer wait.
Mistake 3: No Rate Limiting Awareness
Every API has rate limits, whether documented or not. When your application exceeds those limits, the API will either throttle your requests, returning slower responses, or reject them outright with 429 status codes. If your application does not handle this gracefully, it will appear broken to your users even though your code is technically correct.
The most common scenario is a traffic spike on your website that causes a proportional spike in API calls. Your e-commerce site runs a flash sale, traffic triples, and suddenly your inventory API is rate-limiting every request. Without proper handling, customers see errors on product pages or, worse, can add out-of-stock items to their carts.
Build rate limit awareness into your integration layer:
- Respect rate limit headers. Most APIs return headers like X-RateLimit-Remaining and Retry-After. Read these headers and adjust your request rate accordingly.
- Implement request queuing so that when you approach the rate limit, additional requests are queued rather than immediately sent and rejected.
- Cache aggressively. If the data does not change frequently, cache API responses and serve from cache instead of making a live API call on every request. Product catalog data, shipping rates, and tax calculations are all excellent candidates for caching.
- Implement exponential backoff for retry logic. When you receive a rate limit response, wait before retrying, and increase the wait time with each subsequent retry.
Mistake 4: Tight Coupling
Tight coupling means your application code directly references a specific API's request format, response structure, and endpoint URLs throughout your codebase. When the API changes, or when you need to switch to a different provider, you face a rewrite that touches every file that interacts with that service.
We see this most often with payment gateways and shipping carriers. A business starts with one provider, writes API calls directly in their controllers and models, and then discovers two years later that switching providers requires rewriting hundreds of files.
The solution is an abstraction layer. Define an interface that describes what your application needs from the external service, then implement that interface with a concrete adapter for your current provider. Your application code only interacts with the interface, never with the provider-specific implementation.
This pattern, commonly known as the adapter or gateway pattern, provides several benefits beyond provider portability:
- Testability improves because you can mock the interface in your tests without needing to simulate the actual API.
- Multi-provider support becomes straightforward. You can route domestic shipments through one carrier API and international shipments through another, with both adapters implementing the same interface.
- API version upgrades are contained. When the provider releases a new API version, you update one adapter class instead of every file that makes API calls.
Mistake 5: No Circuit Breakers
A circuit breaker is a pattern borrowed from electrical engineering. When a third-party API begins failing, the circuit breaker "opens" and stops sending requests to that API for a defined cool-down period. Instead, it immediately returns a fallback response or a cached result. After the cool-down period, the circuit breaker allows a small number of test requests through. If those succeed, the circuit closes and normal traffic resumes. If they fail, the circuit stays open.
Without circuit breakers, your application will continue hammering a failing API with requests that are destined to fail, wasting server resources, increasing response times for your users, and potentially making the third-party service's outage worse by adding load during recovery.
Circuit breakers are particularly critical for synchronous API calls in user-facing request paths. If your checkout flow calls a tax calculation API that is down, the circuit breaker detects the failure after a few attempts, opens the circuit, and your application can immediately fall back to estimated tax calculations instead of making each customer wait for the API to time out.
Real-World Failure Scenarios
Understanding these mistakes in the abstract is useful, but seeing how they compound in production makes the urgency clear. Here are three real scenarios we have encountered in client projects:
The Cascading Timeout
An e-commerce site used a third-party API for real-time shipping rate calculations on the cart page. No timeout was configured. When the shipping API experienced a 90-second latency spike, every cart page load waited 90 seconds. The PHP-FPM worker pool was exhausted within minutes. Not only could nobody view their cart, but nobody could access any page on the site. The entire application was down because of one slow API, and the team did not realize the shipping API was the cause for over an hour.
The Silent Data Corruption
A healthcare platform integrated with an external patient records API. The integration code checked for HTTP 200 responses but did not validate the response body. When the API provider deployed a breaking change that modified the JSON structure, the integration continued receiving 200 responses but was parsing the data incorrectly. Patient records were silently updated with wrong information for three days before a nurse noticed a discrepancy.
The Rate Limit Snowball
A fintech application called a credit scoring API for every loan application. During a marketing campaign, application volume tripled. The API rate limit was hit, and every rejected request was immediately retried without any backoff delay. The retry storm consumed the remaining rate limit allowance instantly, creating a cycle where legitimate requests could not get through because retry traffic was consuming all available capacity. The integration was effectively down for six hours.
Building Resilient Integrations
Every API integration in your application should implement these defensive patterns as a baseline:
- Explicit timeouts on both connection and response, configured per API based on expected performance characteristics.
- Comprehensive error handling that distinguishes between retryable and non-retryable errors and provides meaningful fallback behavior for each.
- Circuit breakers that prevent cascading failures by short-circuiting calls to failing services.
- Rate limit awareness with request queuing, caching, and exponential backoff.
- Response validation that verifies the API response matches the expected schema before processing it.
- Abstraction layers that decouple your business logic from specific API implementations.
- Monitoring and alerting that notifies your team immediately when an integration's error rate or latency exceeds normal thresholds.
None of these patterns are complicated to implement individually. The challenge is applying them consistently across every integration point in your application. At Forth Media, we build integration layers with these patterns baked in from the start, so our clients' applications remain stable and performant regardless of what their third-party dependencies are doing. Reach out to us if your API integrations need a resilience audit or a ground-up rebuild.