Start with the business event
An integration starts before the HTTP request. An employee changes status, an order moves forward or a payment completes. Naming that event makes the expected state change easier to understand and test.
Write down what the application knows before the request, what a successful response changes and what must remain unchanged if the provider is unavailable. This is more useful than treating every response as a generic success or failure.
Design for a response you never receive
A timeout does not prove that the provider rejected the operation. It may have accepted the request before the connection failed. Retrying a state-changing operation blindly can create duplicate work.
Use provider-supported idempotency keys where available. Otherwise, persist a local operation identifier and reconcile with the provider before repeating an action. Keep retry limits explicit and separate temporary transport failures from validation failures.
Make the operational state visible
A useful workflow distinguishes pending, completed, failed and needs-review states. People operating the system should understand whether they need to wait, correct an input or investigate.
Record correlation identifiers and sanitized error categories. Avoid placing personal information, access tokens or full payment payloads in application logs. Observability should explain the failure without creating a second problem.
Test the unhappy paths
A fast successful response is only one scenario. Exercise slow responses, duplicate callbacks, unexpected response shapes and a provider recovering after an outage.
The objective is a workflow that can explain what happened and recover deliberately. That is the difference between connecting an API and operating an integration.