
An application has been sending customer orders to a fulfilment provider successfully for two years.
Then orders begin getting stuck.
The application team checks its release history. Nothing relevant was deployed. The integration code has not changed. Tests that use recorded responses still pass.
Yet production traffic no longer behaves the way it did when the integration was built.
That situation is one of the defining problems with third-party integrations: your side of the connection can remain unchanged while the system on the other side continues evolving.
The provider may introduce a new API version. Authentication credentials can expire or be revoked. Usage can grow until an API limit that was irrelevant at launch suddenly matters. A webhook can fail during an outage and never be delivered again. A field that your integration quietly assumed would always contain data may begin returning a new value.
The integration has not necessarily been badly built.
It has been living at the boundary between two systems that change independently.
Third-party integrations fail over time because they depend on external contracts, credentials, limits, infrastructure and behavior that your application does not fully control.
That makes integrations different from much of the code inside your application. An internal function changes when your team changes it. An external integration can change because either side moves.
For Levelworks, this is primarily an Integrable App Health concern. Current & Updated and Observable also matter because integrations need to follow external change and reveal when the assumptions connecting two systems are beginning to fail.
Consider a simple integration:
Your application
↓
Authentication
↓
Third-party API
↓
Response
↓
Your application processes data
For this to keep working, several assumptions must remain true.
Your credentials must still be accepted.
The endpoint must still exist.
The request format must remain valid.
The response needs to contain information your application understands.
Your request volume must remain within the provider's limits.
The provider needs to be available.
If events arrive through webhooks, those deliveries must reach your application and be processed successfully.
An integration can therefore remain untouched in source control while one of its assumptions gradually becomes false.
That is why “we haven't changed that code” is not evidence that an integration should still work.
External APIs are products.
They gain features, replace old functionality, change versions and eventually retire parts of their interface.
Microsoft's current Microsoft Graph policy, for example, states that GA APIs marked for deprecation are generally announced at least 24 months before removal. It also documents examples of non-backward-compatible changes such as removing or renaming a property, changing its type or requiring a new request header. Microsoft Graph versioning and breaking-change policy
Google Maps Platform similarly maintains explicit deprecation and decommissioning lifecycles. Google says most deprecation periods are typically 12 months, after which the affected product, version or feature may no longer be available. Google Maps Platform deprecations
This means an integration has a maintenance clock even if your own product roadmap does not mention it.
A mapping feature, CRM sync or identity integration may continue working perfectly throughout a vendor's deprecation period. That apparent stability can encourage teams to postpone migration until the deadline becomes operationally urgent.
The detailed migration problem deserves its own treatment.
[Internal Link: “API Deprecation: What Happens When a Third-Party Service Changes?”]
The broader lesson is that every important integration should have someone paying attention to the lifecycle of the external interface it uses.
Credentials are another major source of integration failure because authentication is not permanent.
An integration might depend on:
Each has a lifecycle.
Google's OAuth documentation, for example, explicitly warns developers to design for refresh tokens becoming invalid. Reasons can include the user revoking access, administrative policy changes, password changes in certain circumstances, token limits or time-based authorization expiring. Google OAuth 2.0 documentation
This creates a characteristic integration failure:
The connection works for months, then one customer's synchronization stops because their authorization is no longer valid.
If the application treats authentication failure as an ordinary API error, the problem may simply generate repeated failed jobs.
A healthier integration distinguishes the condition and provides a path to reauthorization.
Authentication problems can also be organizational.
A vendor API key may belong to a former employee's account. A certificate may expire without a clear owner, while an integration can lose access when an administrator changes permissions in the external platform.
The technical integration and the administrative ownership behind it both need maintenance.
An API call can continue existing while the caller loses permission to use it.
This is especially common in OAuth-based SaaS integrations.
A provider may introduce new scopes. An administrator may restrict an application. A customer's account permissions may change, or a new feature may require access that the original authorization never granted.
The result is subtle because the integration can be partly healthy.
For example:
Read customers ✓
Read orders ✓
Create shipment ✕
A broad “integration connected” indicator may still report success while the business workflow is broken.
Integration maintenance should therefore think in terms of capabilities, not simply whether authentication succeeds.
An integration that works for 500 customers may not behave the same way at 50,000.
Many external APIs limit the number or rate of requests a client can make.
GitHub's REST API, for example, applies both primary and secondary rate limits and can return HTTP 403 or 429 when those limits are exceeded. Its official guidance recommends respecting Retry-After and rate-limit headers rather than continuing to send requests immediately. GitHub REST API rate limits
GitHub additionally recommends reducing unnecessary polling, avoiding excessive concurrent requests and using backoff when rate-limited. GitHub REST API best practices
The important point is that nothing about the API necessarily changed.
Your application changed around the integration.
Maybe you acquired more customers.
Perhaps a nightly synchronization that once made 10,000 requests now makes 600,000.
Maybe a new feature causes three API calls where one was previously required.
At some point, the integration reaches a constraint that existed from the beginning.
This is why rate-limit handling should not be treated solely as an initial API-integration concern. Usage assumptions need to be revisited as the application scales.
Not every integration fails with a clear HTTP error.
Some failures are semantic.
Suppose your application receives:
{
"status": "active"
}
Your integration assumes the only possible values are:
active
inactive
Later, the provider introduces:
pending
suspended
Adding an enum value may be considered a backward-compatible API change by the provider.
Your implementation may disagree.
Microsoft Graph explicitly lists adding a member to an enumeration among changes that can be treated as backward compatible. It also advises client applications to be prepared to receive properties and types not previously defined. Microsoft Graph versioning guidance
This illustrates an important integration design principle:
A provider's definition of backward compatibility may be broader than your application's assumptions.
Other examples include:
Robust integrations should reject truly invalid data without being unnecessarily brittle about harmless extensions.
Sometimes the API contract stays exactly the same, but the underlying data begins violating assumptions made during development.
A CRM integration may initially encounter customers with one email address each.
Later, enterprise accounts contain several contacts with the same email.
A shipping integration may have been tested only with domestic addresses before international formats begin appearing.
A calendar integration designed around short event names starts receiving unusually long text.
The provider has not broken its API.
Real usage has exposed an assumption in your code.
This is why production integration failures frequently originate in edge cases rather than protocol changes.
Maintenance should distinguish:
The provider changed its contract
from:
Production data revealed that our interpretation of the contract was too narrow.
The fixes are different.
Many integrations use webhooks instead of repeatedly asking an API whether something has changed.
A payment provider might notify your application that payment succeeded.
A source-control platform might send an event when a pull request changes.
That sounds simpler than polling, but webhook delivery introduces another failure boundary.
What happens if your application is unavailable when the webhook arrives?
Provider behavior varies.
GitHub's webhook documentation is a useful illustration. GitHub says failed webhook deliveries are not automatically redelivered; customers can manually redeliver recent events or build mechanisms to identify and replay failed deliveries. GitHub handling failed webhook deliveries
GitHub also expects webhook receivers to acknowledge delivery quickly—within 10 seconds—and recommends queueing the actual processing asynchronously where necessary. GitHub webhook best practices
The general principle is not specific to GitHub:
Do not assume a webhook arriving once means your business process will complete exactly once.
Integrations need to understand:
Otherwise, a brief application outage can leave two systems permanently out of sync.
When an external request fails, retrying can be appropriate.
Blind retrying can amplify the problem.
Imagine 20,000 synchronization jobs encounter a rate limit.
Each immediately retries three times.
The original 20,000 failed requests have now produced tens of thousands of additional calls against the same constrained service.
The integration is effectively helping maintain the outage.
Retry behavior should depend on the failure.
For example:
Failure
Typical response
Temporary network timeout
Retry with backoff
429 rate limit
Respect provider retry guidance
401 invalid credentials
Refresh or reauthorize
403 missing permission
Escalate authorization problem
400 invalid request
Fix request; blind retries will not help
Provider outage
Back off and preserve pending work
GitHub's REST guidance explicitly recommends pausing according to Retry-After or reset information and using increasingly longer delays for repeated secondary rate-limit failures. GitHub REST API best practices
The correct retry policy is therefore part of the integration contract.
If your application depends on another service, some portion of that service's reliability becomes part of your own system.
A customer does not care that checkout failed because Vendor X was unavailable.
They were using your product when it failed.
This does not mean every integration needs complex fault-tolerance engineering.
It does mean teams should understand which dependencies are:
Critical: the application cannot perform an essential function without them.
Important: functionality is degraded, but the core application remains useful.
Optional: failure can be tolerated with limited impact.
That classification affects what the application should do during an external outage.
For a noncritical analytics integration, dropping or buffering events might be acceptable.
For a payment provider, the application may need to prevent duplicate transactions while clearly explaining that processing is temporarily unavailable.
The key maintenance task is periodically checking whether an integration's importance has changed. A service that began as a convenience can become business-critical as product workflows evolve around it.
Many teams do not call vendor APIs directly.
They use an SDK.
That adds another layer:
Your application
↓
Vendor SDK
↓
Vendor API
The SDK itself has versions, dependencies and platform requirements.
Microsoft Graph, for example, currently supports its latest major SDK version with full updates while the preceding major release receives limited-duration security support. Microsoft Graph SDK support policy
An application can therefore be using a currently supported API through an outdated SDK that gradually becomes harder to update, build or support.
This is one reason integration maintenance overlaps with dependency maintenance without being identical to it.
[Internal Link: “Why Dependency Updates Are Essential to App Maintenance”]
Not every integration failure comes from code.
Production configuration can drift.
A webhook URL changes but the external provider still points at the old address.
A secret is rotated in one environment but not another.
An IP allowlist no longer includes the application's new outbound address.
An environment variable differs between staging and production.
These failures are especially frustrating because local tests and code review may find nothing wrong.
The actual integration contract includes configuration outside the source repository.
Important integration configuration should therefore have:
This is one of the least technical and most common causes of long-term failure.
An integration is built as part of a project.
The project launches.
The developer who built it moves elsewhere.
Two years later, the provider announces an API change to an inbox nobody monitors.
Or a client secret needs rotation, but nobody knows which team owns the external developer account.
The code is still owned.
The relationship is not.
Every important integration should have clear ownership of:
This becomes particularly important when applications are handed between teams or vendors.
A third-party dependency without an owner is effectively a future incident waiting for somebody to notice it.
Weak integration documentation says:
Uses Vendor X API.
Useful integration documentation says:
Orders are created through Vendor X API v3. Authentication uses OAuth with offline access. Failed creates retry with exponential backoff; requests must be idempotent. Shipping status arrives through webhooks. Nightly reconciliation compares orders changed during the previous 24 hours to recover missed webhook events.
The second version describes how the relationship actually works.
For important integrations, document:
You do not need to duplicate the vendor's documentation.
Record the parts of its contract your application depends on.
Periodic integration maintenance does not need to be complicated.
Review important integrations and ask:
Area
What may have changed?
API
Version, endpoints, deprecated features
Authentication
Tokens, secrets, scopes, account ownership
Usage
Request volume, quotas, rate limits
Payload
Fields, enum values, pagination, data formats
Webhooks
Endpoint, retries, missed-event recovery
SDK
Supported version, dependencies
Configuration
URLs, allowlists, environment settings
Business importance
Has this integration become more critical?
Ownership
Is someone still receiving provider notices?
That review is especially valuable for integrations that are quiet when healthy.
The fact that nobody has touched one for two years should increase curiosity, not decrease it.
This article is about why integrations degrade.
Detecting those failures reliably is a related but separate problem.
A mature application should be able to distinguish whether synchronization failed because of authentication, throttling, invalid data, webhook delivery or provider availability rather than reporting everything as “integration error.”
The mechanics of monitoring request success, latency, retries, event lag and reconciliation deserve deeper treatment on their own.
[Internal Link: “How to Monitor the Health of Your App’s APIs and Integrations”]
Similarly, credentials and authentication require security maintenance beyond simply keeping the connection functional.
[Internal Link: “API Security Maintenance: How to Keep Integrations Secure Over Time”]
Fresh integrations receive attention.
They are tested during development, watched closely after release and understood by people who recently built them.
Years later, the dangerous integrations are often the quiet ones.
They have worked so reliably that nobody thinks about them. The original engineer has moved on. Documentation is thin. Provider emails disappear into a shared inbox. Usage has multiplied while old capacity assumptions remain embedded in the implementation.
Then one boundary moves.
A token expires. A quota is reached. A webhook is missed. An API version is retired. A new payload value reaches code that never expected it.
Suddenly a dependency that looked maintenance-free becomes production work.
That is why Integrable App Health is not established when an integration first succeeds. It is preserved by continuing to understand the external systems your application has chosen to depend on.
Every third-party integration is, in effect, an agreement between two moving systems.
The code is only the part of that agreement you control.