Skip to content
Back to journal

An Integration Is a Product Surface

How to make a third-party integration clear to users, safe to retry, and recoverable when a dependency does not behave as planned.

An integration is easy to underestimate when it is described as a technical task: connect the payment provider, sync the CRM, call the shipping API. From the customer’s perspective, though, it is part of one product journey. They do not care where the handoff happens. They care whether an invitation was sent, an invoice was paid once, or a shipment can be found.

That makes an integration a product surface. It needs an understandable contract, clear states, safe recovery, and someone accountable for its behaviour after release. A successful request in a dashboard is not enough.

Start with the outcome people can recognise

Begin with the job, not the provider. “Connect the accounting platform” is a project label. “A finance manager can send an approved invoice once and see whether it reached the accounting system” is a product requirement.

That sentence exposes decisions worth making early:

  1. What event starts the handoff?
  2. What information is essential, and which system owns it?
  3. What does accepted, processing, complete, and needs attention mean to the person waiting?
  4. What happens when the dependency is slow, unavailable, or rejects the request?
  5. Who can retry, cancel, correct, or escalate the action?

The answers belong in the product flow, interface copy, API contract, and tests. If the team can only say “we got a 200,” it still has not defined the user’s outcome.

Make the state visible, including the uncertain state

Many integrations are asynchronous. A product may submit work successfully and still need to wait for a remote system, a webhook, or a reconciliation job. Avoid presenting the first successful network response as proof that the customer’s job is complete.

Show a useful state instead: sending, queued, confirmed, rejected, or needs review. Pair it with the next sensible action. “We could not confirm your payment” is more honest and more useful than “Something went wrong” when the correct next step is to wait, check a reference, or contact support.

The same clarity matters in the interface between systems. RFC 9457’s problem-details format gives an API a structured way to provide a stable problem type, a human-readable explanation, and an occurrence identifier. It is not a replacement for product design, but it can keep a mobile app, a web client, and a support tool from each inventing a different response to the same failure.

Do not expose stack traces, internal host names, or provider credentials in that detail. The standard explicitly cautions that problem responses can leak information useful to an attacker. Give customers a message that helps them act, and give support a safe reference they can use to investigate.

Treat retries as a product decision

The most expensive integration bugs often live in the gap between a request being sent and its result being known. A customer taps “Pay,” their connection drops, and nobody can immediately tell whether the payment provider received the request. Retrying blindly can create a duplicate charge, duplicate order, or duplicate message.

HTTP’s semantics distinguish operations that can safely be repeated from ones that cannot. A client should not automatically retry a non-idempotent request unless it can determine that the operation is safe to repeat or that the original was never applied.

For a consequential action, design that certainty deliberately:

  • Generate a stable, non-sensitive request identifier before sending the action.
  • Store the identifier and the resulting business record together.
  • On a repeated request, return the original result or an explicit in-progress state—never create a second action.
  • Give the user one visible reference for the action, even if several systems participate.

This is not just defensive backend work. It determines whether the interface can honestly offer “Try again,” whether support can answer “did it go through?”, and whether the business can reconcile an uncertain outcome without guessing.

Define the boundary, not only the endpoint

An endpoint description is useful, but it is not the whole agreement. A dependable integration contract names the request shape, authorization, expected result, error cases, retry behaviour, time limits, and the events sent back afterward.

OpenAPI can document operations as well as incoming webhooks, which makes it a practical shared artifact for teams that both send and receive events. Keep the documentation close to the implementation, but use it to support a conversation rather than to replace one.

For every important handoff, agree on a small set of examples:

  • a valid first submission;
  • the same submission repeated after a timeout;
  • a rejection caused by data the user can correct;
  • an authorization failure;
  • a delayed or duplicate callback; and
  • a provider outage or malformed response.

Those cases turn “the API works” into testable behaviour. They also reveal whether the integration needs a queue, a reconciliation job, a manual-review state, or a less ambitious first release.

Keep ownership after the launch

Third-party behaviour changes: credentials expire, rate limits are reached, payloads evolve, and a dependency can degrade without a clean error. The OWASP API Security Top 10 highlights risks around authorization, sensitive business flows, and unsafe consumption of APIs. These are product risks as much as security risks: an integration that acts on the wrong account or repeats a critical operation breaks trust fast.

Give the integration an owner and a small operating record. It should include the user promise, system-of-record rules, time and retry limits, support reference, health signals, and a decision for pausing or disabling the path. Review it after real use, especially where people abandon, retry, or contact support.

The goal is not to make every dependency invisible. It is to make the handoff dependable enough that customers understand what happened and the team can recover when the answer is not yet clear.

If your product needs design, engineering, and quality to hold the same line across a critical integration, bring BugSquad the challenge.