← Technical series

Reliable .NET integrations

Handling API failures without duplicate actions

A practical walkthrough of rate limits, account-access errors, and retry decisions in a modular .NET integration layer.

An API request can fail before it reaches the provider, after the provider rejects it, or after the provider has already completed the action. Those situations need different responses.

For a read operation, repeating the request may be harmless. For a customer email, a payment, or a new CRM record, the same decision can create a duplicate. Reliable integration starts by understanding the operation, then choosing a failure policy.

1. Give the application a useful failure signal

The shared HTTP layer in this .NET integration example distinguishes rate-limit responses from account-access errors and other API failures. That gives the application more useful information than a single “request failed” message.

Different failures call for different decisions
SignalApplication decision
429: rate limitConsider a bounded retry using the provider's timing information and the operation's deadline.
402: provider-specific account restrictionSurface the account issue. Repeating the same request will not resolve the underlying restriction.
Timeout after sendingTreat the outcome as uncertain. Check whether the action completed before repeating a write.
Invalid requestCorrect the input or integration contract before trying again.

The client's rate-limit exception exposes retry timing. It does not make the business decision to retry automatically. That distinction keeps the library useful across applications with different deadlines and tolerance for duplicate actions.

2. Keep retry policy close to the business operation

A background contact synchronization and an interactive customer-support response have different needs. The background job may wait for capacity. The support screen needs a timely, accurate status that the operator can act on.

Choose an attempt limit, an overall deadline, and a final failure path. Decide which layer owns retries so that a job runner, HTTP policy, and application service do not each multiply the attempts. Record enough context to distinguish the original action from a retry.

A useful review question

If the provider completed this request but the response was lost, what would happen when the application tries again?

3. Record intent before repeating a write

For a workflow with important side effects, give the intended operation a stable identity. Record its state, attempt history, and any provider reference returned. If the API supports idempotency keys for that operation, use the documented mechanism.

A local operation ID alone cannot prevent duplicates at the provider. When the API offers no suitable deduplication or lookup mechanism, an uncertain result may need reconciliation or human review. Marking it as simply “failed” hides the decision that still needs to be made.

  1. Record the intended action
  2. Call the provider
  3. Confirm, retry, or reconcile
An example application workflow around an API client.

4. Test the failure paths that change behavior

Tests for the shared client cover rate-limit timing and account-access errors. They check that the calling application receives enough information to choose the next action.

The application needs its own checks around that boundary: an exhausted retry budget, an account restriction, an uncertain response, and a worker restarting during an operation. Mocked client tests cannot establish how every live account or network failure will behave.

Apply the same discipline when an AI assistant initiates the action. The model can propose an operation, but execution still needs permissions, an operation record, and an explicit policy for uncertain results.

What to inspect in your integration

  • Which calls change external state, and how are duplicates detected?
  • Does each failure reach a useful status for the operator or calling system?
  • Which component owns retries, and when does it stop?
  • Can support trace an attempted action without logging secrets or unnecessary customer data?

Engineering context & further reading

The account-access meaning of HTTP 402 is specific to this provider. An operation ledger and reconciliation workflow belong to the application consuming the integration client.

Work together

Resolve the next decision
in your system.

Discuss your current design, the risks you see, and what needs to move forward.

Discuss your requirements