Integration contract
Define what happens before, during and after the happy response
Treat the provider as an independent system that can be slow, duplicated, unavailable, changed or compromised.
Contract
Pin the operations, schemas and semantic meaning you actually use.
- Specify
- Version, fields, units, time zones and null behavior
- Failure
- Provider response remains valid JSON but changes meaning
- Evidence
- Contract fixtures and compatibility tests
Identity and trust
Authenticate both outbound requests and inbound callbacks.
- Specify
- Credential scope, signature, issuer and rotation
- Failure
- A public endpoint accepts forged webhook events
- Evidence
- Signature, timestamp and replay negative tests
Retry and idempotency
Make repeated attempts safe and bounded.
- Specify
- Retryable states, backoff, key and terminal outcome
- Failure
- Timeout creates duplicate charge or message
- Evidence
- Duplicate and delayed-delivery tests
Limits and degradation
Plan for quotas, latency and unavailable features.
- Specify
- Budget, timeout, concurrency and fallback
- Failure
- One dependency consumes all request capacity
- Evidence
- Load boundary and provider-outage exercise
Operations and exit
Own the telemetry, reconciliation and replacement path.
- Specify
- Correlation IDs, reconciliation, export and owner
- Failure
- Silent provider drift is found by customers
- Evidence
- Dashboard, runbook and representative export
Operating principle
Design external calls as uncertain distributed work
Generated integration code often treats a remote API like a local function: call, parse and continue. Networks and providers create ambiguous outcomes where your request timed out but the provider completed it.
Give each operation an idempotency strategy, correlation context and reconciliation path. Separate temporary dependency failure from invalid user input and permanent business rejection.
- Authenticate inbound callbacks
- Bound timeouts and retries
- Preserve provider request identifiers
- Reconcile consequential operations
Applied example
Failure example: the successful timeout
A checkout call times out after the payment provider created the charge. The application retries without an idempotency key and creates a second charge.
- The local timeout did not establish provider failure
- The operation had financial consequence
- Retry behavior was not part of the contract
- Reconciliation identifiers were missing
Plain answers
Questions to resolve before shipping
Should I retry every failed API request?+
No. Retry only explicitly retryable states and only when the operation is idempotent or protected by an idempotency mechanism.
Are SDKs safer than direct HTTP calls?+
They can implement provider conventions, but you still own credential scope, semantic validation, retries, observability and upgrade review.
What should be mocked in tests?+
Use controlled fixtures for contract cases and also test a staging or sandbox integration for authentication, provider behavior and operational assumptions.