Skip to content
Web Projects

When Your Website Depends on Another Service, What Happens When It Fails?

13 min read
Appointment-booking website connected through an integration service to a calendar provider, with confirmed and pending outcomes shown as separate paths.
In this article

A customer chooses an appointment on a business website and selects Confirm. The button shows a loading indicator, then an error: “Something went wrong. Please try again.” The customer clicks again.

There is one question the interface cannot answer from that error alone: did the booking provider already receive and accept the first request? If it did, the second click could create a duplicate appointment. If it did not, telling the customer that the appointment was booked would be equally misleading.

This is one reason the reliability of a business website cannot be judged solely from its pages. When a website depends on external booking, payment, delivery, messaging, or customer-management services, it also depends on the promises and failure behavior of those connections.

The booking example below is hypothetical, not a description of a Technway client incident. Its purpose is to show how a business and engineering team can agree on reliable behavior before an integration becomes a source of lost transactions or customer confusion.

A timeout is not the same as a rejected booking

A website may receive a clear refusal from the booking service: the chosen time is unavailable, a required field is invalid, or authorization failed. That result can usually be shown to the customer with an appropriate next step.

A network timeout is different. It means the website did not receive a usable response within the expected period. The request might never have reached the provider. It might have reached the provider and failed. Or it might have succeeded while the response was lost. The transport error does not, by itself, establish which outcome occurred.

This distinction is particularly important for operations that change something: reserving an appointment, creating an order, capturing a payment, or sending an instruction to another system. A read-only request can often be retried without changing business records. Repeating a creation request can have a different consequence.

The first requirement for a reliable integration is therefore not “show an error when the API fails.” It is “represent what we actually know about the business operation, including when we do not yet know the outcome.”

Start by deciding which system can confirm the result

For the hypothetical appointment site, the external booking provider may own the availability calendar and the authoritative reservation record. The website can collect the visitor’s request, validate its form, and display the journey, but it should not call an appointment confirmed simply because its own button handler completed.

Before implementation, establish which event makes a booking real. Is it a provider response containing a reservation identifier? A confirmed status retrieved from the provider? A later notification? A human administrator’s approval? The answer depends on the provider’s contract and the business’s actual process.

The team also needs to know whether the provider supports retrieving a request by an operation identifier, whether callbacks are available, how long an unresolved request can remain pending, and who is responsible when systems disagree. An integration cannot reliably display or reconcile a state that the partner system does not make observable.

This work is not unnecessary architecture planning. It determines whether the website may truthfully say “Confirmed,” should say “We’re checking,” or must say that no reservation was made.

Follow one request through an uncertain result

Consider an illustrative sequence. A customer chooses a valid appointment and submits it. The website sends a request to the booking provider. The provider creates the reservation, but the network connection drops before the website receives the confirmation.

From the website’s perspective, the result is unknown. From the provider’s perspective, the appointment exists. If the interface reports failure and invites an unrestricted retry, the customer may inadvertently request the same appointment twice. If it reports success without checking, it could mislead customers in cases where the request really did fail.

A better design depends on what the provider offers. If it supports a stable client-generated operation identifier and an appropriate status lookup, the website can associate retries and later checks with the same logical attempt. If it supports an idempotency mechanism for booking creation, repeated delivery of the same intended operation can be handled without creating a second booking, subject to that provider’s documented guarantees.

If the provider offers neither reliable status lookup nor safe retry behavior, the website should not improvise “exactly once” behavior in its UI. The honest response may be a pending status with a clear support or manual reconciliation path, rather than another booking request.

The attempt also needs to remain identifiable after a browser refresh or interrupted connection. A transient loading indicator is not a recovery record. The website should retain or retrieve an appropriate operation reference securely, so staff or customers can investigate the same request without exposing another person’s booking. How that reference is stored and accessed depends on the provider and the site’s authentication model.

Make the possible outcomes explicit

An integration’s visible behavior should be designed around distinguishable outcomes, not just a green success state and a red error state. This table describes options for the illustrative booking journey; the actual provider and business policy determine which are available.

Observed outcomeWhat can be concludedAppropriate next step
Provider confirms reservation with referenceBooking is confirmed under the provider’s contractDisplay confirmation and reference
Provider explicitly rejects requestNo reservation created for that attemptExplain reason; invite correction
Request dispatched; response times outOutcome unknown, not necessarily failedCheck status or reconcile; prevent unsafe duplicate
Request demonstrably never sentNo provider operation startedAllow a controlled new attempt
Provider acknowledges request as pendingRequest received; booking not yet finalShow pending; update after verified result
Duplicate submission or delayed callbackSame attempt may be observed more than onceDeduplicate according to documented contract

The table is also an acceptance-criteria discussion. The business must decide whether a pending request is allowed, how long it remains visible, and who resolves it. Without those decisions, a developer can implement a technically correct API call but still deliver an incorrect customer promise.

Retries need to be safe, limited, and justified

A temporary connectivity failure may be recoverable, but simply retrying every unsuccessful call is not a resilience strategy. Microsoft’s guidance on transient faults (opens in a new tab) recommends retrying only appropriate failures, using timeouts and back-off, and avoiding retry policies that overwhelm an already struggling dependency.

Creating a booking has a side effect. If the provider already accepted the first attempt, a second request may create a second record unless the operation is protected against duplicates. The Amazon Builders’ Library (opens in a new tab) explains why idempotent API design matters when a request can succeed even though its response does not reach the client.

Some providers have explicit retry guarantees. For example, Stripe documents idempotency keys (opens in a new tab) for supported creation and update requests. That is evidence about Stripe’s API, not a guarantee that an unrelated booking platform supports the same mechanism. The integration design must follow the provider actually being used.

Retry decisions also belong at a defined layer. If a browser, application server, and provider client library all retry independently, one customer action may trigger more attempts than anyone expects. An engineering team should know where retry control lives, which errors qualify, and when it stops.

The customer needs a truthful next step

A polished interface cannot repair an uncertain business state by changing the wording of the error. But clear communication can prevent the uncertainty from becoming an additional user problem.

A confirmed reservation can show its actual reference and details. A rejected reservation can explain what needs correcting. For an unresolved request, the interface should avoid both a false confirmation and instructions that might create another booking. A status-check option, reference number, or customer-service path is useful only if the underlying process genuinely supports it.

An example of honest pending-state copy might be:

“We couldn’t confirm your appointment yet. Please check its status before submitting another request. If the status does not update, contact us using this reference.”

This message is appropriate only when the business really has a status check and a support team capable of using the reference. If not, the wording and operational plan must change. User-facing promises should describe a working process, not a feature the team intends to build later.

Status updates also need to be accessible. The W3C’s guidance on status messages (opens in a new tab) explains how information about progress, results, and errors should be programmatically determinable so assistive technologies can announce it when appropriate. The interface should also preserve a usable way to leave or revisit the journey without losing essential information.

A fallback is a business decision, not just a technical one

When the provider is unavailable, should the site stop taking bookings, collect requests for later confirmation, or offer a different channel? Those approaches create very different commitments.

Collecting an appointment request for manual review may work for a small service business with staff available to follow up. It is not the same as reserving a specific time. Continuing to accept “confirmed” bookings into an unverified local queue could overbook capacity or create conflicting records if the provider remains the source of truth.

A graceful fallback must state its limitations. If requests will be processed later, the customer needs to know that the appointment is not confirmed. The business needs a real process for handling the queue, communicating outcomes, and avoiding lost or duplicate requests. If those conditions cannot be met, temporarily disabling booking may be the more responsible choice.

The right fallback follows business capacity and the consequences of failure. A simple enquiry form can tolerate a different recovery process from a paid reservation or time-sensitive medical appointment. The architecture should be proportionate to the transaction being protected.

Test failure outcomes before going live

A successful test booking proves very little about the failure cases. The launch review should deliberately simulate the conditions most likely to mislead customers or create inconsistent records. These are illustrative test targets, not a record of completed Technway testing.

Failure scenario to simulateRequired evidenceRisk it addresses
Normal successful reservationProvider reference and correct user confirmationFalse or incomplete success
Clear rejection or unavailable slotNo booking; understandable corrective messageMisleading success or dead end
Provider accepts, response is lostUnknown state handled without creating duplicateRepeated booking
User double-clicks or retries after delayOperation correlation and safe outcomeDuplicate side effects
Callback arrives late or twiceState reconciliation preserves correct final resultIncorrect status transitions
Provider stays unavailable, then recoversBounded retries, fallback, ownership and recoverySilent loss or retry storm

One especially revealing test is to make the provider accept the booking, then prevent the website from receiving the response. That is the case a happy-path demo almost never shows. The expected behavior should already be agreed before the test is run.

Monitor completed business outcomes, not merely API availability

An integration may have a high availability percentage while still losing important operations. A health endpoint can respond normally while a particular booking action fails due to changed permissions, invalid data, or a downstream dependency.

Monitoring should connect the stages of an important journey: request initiated, accepted or rejected by the provider, final state delivered to the user, and any later reconciliation. When possible, use an operation identifier that helps correlate those stages without placing unnecessary personal information into logs.

The operational handover needs the same clarity. Who receives an alert when unresolved bookings accumulate? Who can inspect the provider’s records? Who contacts the customer after a disputed outcome? What happens if a callback is delayed or duplicated? The technical system and the support process together determine whether a failed operation can be recovered.

This is also where maintenance responsibility becomes relevant. Integrations can change after launch: credentials expire, permissions are revised, response formats evolve, and provider incidents occur. Our maintenance and technical support service describes how ongoing responsibilities can be defined rather than left implicit.

Design the necessary resilience, not the most elaborate architecture

A small business website does not automatically need distributed queues, elaborate orchestration, or a circuit breaker around every external request. Those patterns introduce implementation and operational costs of their own.

Start with the minimum trustworthy contract: the authoritative system, the states customers may see, a bounded retry policy where safe, a way to investigate unresolved operations, and an owner for recovery. Add queues, automatic reconciliation, or more advanced fault isolation when transaction volume, failure consequences, or provider characteristics justify them.

The decision should be explainable in business terms. What could the failure cost? How quickly must a customer receive certainty? Can the provider supply a reliable status? What can staff handle manually? The answers determine which engineering mechanisms are worth maintaining.

A website is reliable when its promises survive uncertainty

The strongest integration is not necessarily the one that never displays an error. Every external service can be slow or unavailable. Reliability means recognizing what is known, being honest about what remains uncertain, and providing a safe path to completion or recovery.

For the hypothetical booking website, that starts with a simple distinction: sending a request is not confirming an appointment. Once that distinction is understood, decisions about retries, status messages, monitoring, and support become much more coherent.

The value of planning for failure is not technical sophistication for its own sake. It is protecting the business from duplicate actions, silent losses, and promises the underlying systems cannot keep.