A network timeout creates uncertainty. The client did not receive a response, but the server may already have completed the requested operation. Sending a fresh request can then create a second result when the application intended only one.
Idempotency keys help a service recognize repeated attempts at the same operation. For a startup integrating external APIs, the key decision is how to preserve that identity across retries and recovery.
Model the operation before the attempt
Imagine an application creating one external customer record. The logical operation is “create the customer associated with this local record.” A timeout and a retry are separate attempts to complete that same operation.
Generate and retain an idempotency key for the operation where the API supports it. Do not automatically generate a new key every time the network request is sent.
Stripe documents that its API v1 stores the response after endpoint execution begins and returns the saved result for subsequent requests using the same key. Its documentation also distinguishes API v2 behavior, so the contract must be checked for the API version being used.
The broader lesson is to implement the provider’s actual rules rather than assuming all idempotency systems behave identically.
Preserve the request’s meaning
A retry should remain associated with the same intended input. Reusing one key while changing the operation’s parameters creates ambiguity.
For example, a request to create one record with one set of attributes should not silently become a different request after a timeout. If the input needs correction, first establish what happened to the original attempt.
Stripe’s error-handling guidance explains that a lost connection does not reveal whether execution occurred. It also warns against starting a new operation with a new key while the original outcome remains unresolved.
This is an application-state problem as much as a networking problem. The local system needs to remember what it attempted and what remains unknown.
Make uncertainty visible in the workflow
Use an explicit pending or unresolved state rather than immediately declaring failure when the response is missing.
For the illustrative customer-creation flow, retain the local operation identifier, the idempotency key, and any confirmed external identifier. Keep request details sufficient to reconcile the outcome without exposing unnecessary sensitive data.
A support view can then distinguish “not attempted,” “confirmed complete,” and “outcome being checked.” Those states support better decisions than one generic error label.
The same reasoning applies to automated workers. A restarted worker should be able to recognize an existing logical operation rather than inventing a new one simply because its process memory was lost.
Test the ambiguous cases
A successful request is only the first test. Simulate a response being lost after the server accepts the operation, then confirm that the retry does not create an unintended duplicate.
Also test simultaneous attempts and the provider’s documented key-retention boundaries. Decide how the application reconciles an unresolved operation once automatic retry is no longer appropriate.
Do not interpret idempotency as unlimited permission to retry indefinitely. Retention, concurrency, and error behavior are part of the provider’s contract.
A reliable integration keeps each retry attached to a known operation and treats an unknown outcome as something to investigate. That design reduces duplicate side effects while giving the team a clearer path through ordinary network failures.
