Resources · 18
Make API integrations resilient to outages
Map dependencies, bound retries and keep essential journeys usable during external failures.
· 9 min
What this guide helps achieve
- Connect APIs to business journeys
- Bound calls and retries
- Plan degraded operation
- Measure recovery
Quick check
- Which journeys depend on each provider?
- Does every call have a timeout?
- Could a retry duplicate an operation?
- What does the user see during failure?
- Who approves return to normal service?
Step-by-step method
- 01
Map calls
Connect every integration to exchanged data, contracts, owners and journey steps. Identify synchronous calls that block the user.
Deliverable: prioritised dependency map.
- 02
Set time budgets
Define a timeout for each call and a total budget per journey. Prevent service chains from multiplying wait times.
Deliverable: timeout and threshold matrix.
- 03
Bound retries
Retry only operations safe to repeat. Test idempotency, cap attempts and spread them with suitable backoff.
Deliverable: tested retry policy.
- 04
Plan degraded operation
Decide what remains usable, which data may be queued and what clear message appears during an outage.
Deliverable: fallback behaviour per journey.
- 05
Simulate incidents
Introduce latency, invalid responses and outages in a controlled environment. Check load, data, interface and restoration.
Deliverable: failure test results.
- 06
Watch outcomes
Track errors, latency, queues and business actions actually lost. Assign escalation and supplier coordination owners.
Deliverable: dashboard and recovery procedure.
Management indicators
| Indicator | What it measures | First action |
|---|---|---|
| Mapped journeys | Essential journeys with known dependencies | Assign owners to unknown calls |
| Time budget | Calls within the journey deadline | Review chained waits |
| Safe retries | Repeated operations without side effects | Add idempotency or remove retry |
| Tested degradation | Outage scenarios with observed user result | Improve continuity and communication |
Common pitfalls
- Retrying without limit against an overloaded service
- Repeating a non-idempotent write
- Hiding an outage behind unlabelled stale data
- Measuring only provider response rate
Frequently asked questions
Should every request be retried?
No. Retries help selected transient failures and must respect the overall deadline, idempotency and provider load.
Is a circuit breaker sufficient?
It protects some calls, but does not define the user experience or recovery of queued work.
What should be measured first?
Effects on essential journeys: duration, lost or delayed actions and recovery quality.
References: data, uses and limitations
Documentation reviewed on .
| Source and purpose | Verified data or benchmark | How to use it | Limitation to retain |
|---|---|---|---|
| OASIS · TAXII 2.1 Exchange threat intelligence through an application protocol. |
TAXII 2.1 is an OASIS Standard dated 10 June 2021. It includes service discovery and access to collections. | Test authentication, collection permissions, pagination and recovery after interruption. Record which objects were actually received and processed. | TAXII transports data; it replaces neither the content model nor assessment of reliability. |
ETag, HTTP caching and concurrent updates
A retry must not overwrite a newer version
Separate a network failure, a failed precondition and the retry decision. A 412 is not an invitation to resend the same write repeatedly.
- Keep the ETag with the representation used to prepare PUT.
- After 412, read again and resolve the conflict; backoff alone does not reconcile edits.
- Document duplicates and requests with unknown outcomes separately: they are outside this precondition simulator.
Explore ETag comparisons and the simulator →
References reviewed · RFC 9110 · §13 · RFC 9111 · RFC 6585 · §3
Idempotence and API retry contracts
Compare an HTTP property with a provider contract
HTTP idempotence concerns the intended effect of identical requests. Application retry keys belong to the API’s contract. Stripe details below are attributed to its documentation accessed on 22 October 2026, apply to its APIs and are not simulated by the budget model.
After a lost response, connect the operation to verified business state. Then check operation identity, retry contract and context. Finally choose reconciliation or a bounded retry; arbitrarily changing the key does not prove absence of an earlier effect.
Six Stripe differences or limits to document
| Comparison | API v1 | API v2 |
|---|---|---|
| Methods accepting keys | POST accepts keys. Sending one on GET or DELETE has no effect under this contract. | POST and DELETE accept keys; GET is idempotent by definition and a key has no effect. |
| Reused result | After execution begins, the initial status and body are saved; a retry can return the same 500 error. | Successful work is not repeated. Failed or partially failed work can be retried for an updated response; an impossible replay returns an explanatory error. |
| Window and retention | The dedicated page permits pruning after at least 24 hours. A key reused after pruning creates a new request. | Documented replay is within 30 days for the same API and account or sandbox. |
| Parameters and scope | The layer compares parameters with the original request and rejects incompatible reuse. | Same API and same account or sandbox are part of replay conditions; review the exact endpoint contract. |
| Before execution | A validation failure or concurrency conflict that does not initiate the endpoint saves no idempotent result, according to the v1 page. | Do not copy a v1 exception without checking v2 documentation and the endpoint being used. |
| Durable identity | A key should remain tied to one intention and its parameters; documentation advises against sensitive data in keys. | Automatic service-side key generation does not remove the client’s need to associate retries with the correct operation. |
Status is not everything: Stripe-Should-Retry
| Documented value | Stripe guidance | Limit |
|---|---|---|
| true | Retry using exponential backoff under the error-handling documentation. | Also check operation identity, context, budget and contract. |
| false | Do not retry the request. | Do not replace this signal with a generic “every 5xx can be replayed” test. |
| Absent | Decide using status and other response information. | Absence neither guarantees no effect nor requires a retry. |
Four retry situations needing different evidence
Response lost after sending
A client does not receive a creation response.
Find the operation and state in the authorised source; retain the key if the contract permits replay of that same intention.
A new key can describe a new operation and produce another effect.
Same key, changed parameters
The client changes content while reusing a key.
Compare parameters with the contract and separate correcting a request from repeating it identically.
The described v1 contract rejects incompatible parameters; do not work around this with a new key without a business decision.
Key outside its replay window
The application wants to replay an old request.
Review duration, API, account and business state; do not assume the provider retains the first result forever.
An old key is not evidence of permanent uniqueness.
Two workers for one effect
Two workers both read “effect absent”.
Test atomic claiming of the local effect and the external-effect contract; retain both receipts.
A preliminary SELECT or local constraint alone cannot guarantee uniqueness at a remote provider.
Keep three identities separate
| Identity | Role in a webhook example | Limit |
|---|---|---|
| Request key | Recognise a repeated client request under an API contract. | It is not automatically the identifier of a received event. |
| Event identifier | Connect repeat deliveries from a provider and its context. | Different events can concern the same business effect. |
| Business-effect key | Prevent a repeated chosen local business action using an appropriate atomic mechanism. | A remote effect needs its own guarantee, controlled recovery and reconciliation. |
Explore Retry-After and the retry model →
Primary sources and limits
The RFCs define the cited HTTP elements. AWS describes design choices and Stripe documents its own APIs. Budgets, local waits, cases and diagrams are educational: they neither measure your service nor execute requests.
- IETF · RFC 9110 — Retry-After et idempotence HTTP · June 2022 · STD 97
§5.6.7; §9.2.2; §10.2.3; §15.6.4 - IETF · RFC 6585 — 429 Too Many Requests · April 2012 · Standards Track
§4 - AWS Builders’ Library · Timeouts, retries, and backoff with jitter · Published 2019-12-05; accessed 2026-10-22
Retries; jitter; timeout scope - Stripe · Idempotent requests · Documentation accessed 2026-10-22
API v1: saved results, parameters, key pruning, execution boundary - Stripe · API v2 overview — Idempotency · Documentation accessed 2026-10-22
POST/DELETE; same API and account/sandbox; 30-day replay window - Stripe · Advanced error handling · Documentation accessed 2026-10-22
Stripe-Should-Retry; status codes; idempotency
References reviewed
OAuth/OIDC: audience and access
Token renewal does not replace access-removal procedures
Separate session, access-token and refresh-token lifecycles in operations. Local sign-out does not prove they all become invalid simultaneously.
- Measure residual access using authorised test accounts and objects.
- Exercise expiry, revocation and provider outage without logging secrets.
- Record expected responses and the owner responsible for restoring the integration.
See token recipients and the ten OAuth/OIDC cases →
Sources reviewed on · IETF · RFC 9700 · OAuth 2.0 Security BCP · IETF · RFC 9068 · JWT access token profile · OpenID Foundation · OpenID Connect Core 1.0 · IETF · RFC 8725 · JWT Best Current Practices · IETF · RFC 6749 · OAuth 2.0 framework
Webhooks: signatures and replay
API recovery and webhook recovery follow different contracts
For incoming notifications, track the event, transport attempt and business effect separately. A signature authenticates a message; it is not an idempotency key.
- Retain required raw bytes and authenticate each new attempt.
- Plan provider-specific recovery: Stripe can retry automatically; GitHub does not automatically redeliver failures.
- Test lost responses, concurrency and post-outage reconciliation.
See webhook signatures, digests and the ten cases →
Sources reviewed on · Stripe · Webhooks · Stripe · Manage webhook endpoints · GitHub · Validating webhook deliveries · GitHub · Best practices for using webhooks · GitHub · Handling failed webhook deliveries
SSRF: URLs and connections
A retry does not change destination policy
Resilience for a URL importer must preserve egress controls. A fallback address, proxy or redirect introduces another step to verify, even when the original string passed the application contract.
- Use the same parser and fields for validation and the HTTP client.
- Bind validated addresses to actual connections while preserving TLS and the original hostname.
- Test refusals and limits in an authorized lab without probing third-party services.
Read the 12 cases and connection controls →
Sources reviewed on · OWASP · SSRF Prevention Cheat Sheet · WHATWG · URL Living Standard · AWS EC2 · Instance metadata options · IETF · RFC 3849
Pagination: consistency and recovery
Recovery follows the batch actually retained
A retry needs to know which objects were retained and under which view. Advancing continuation before confirming a batch can lose data; rereading requires deduplication and an external-effects policy.
- Test a crash between batch retention and checkpointing.
- Do not infer completion from page size alone.
- Recheck permissions and reference validity on every recovery.
Compare computed reads and recoveries →
Sources reviewed on · Google · AIP-158 Pagination · PostgreSQL 18 · LIMIT and OFFSET · PostgreSQL 18 · Row constructor comparison · PostgreSQL 18 · Transaction isolation · OWASP · API1:2023 Broken Object Level Authorization
API errors: types, statuses and evidence
Handle an error without parsing its sentence
An API client may receive a translated title, missing member or unfamiliar extension. Preserve decisions based on the documented type and HTTP status, then connect a safe action to the context.
- Compare received status and JSON status without silently replacing either.
- Test absent type, string status instead of a number, and an unknown extension.
- Separate person-facing text, business code and occurrence reference.
Explore problem types and eight fictional responses →
IETF · M. Nottingham, E. Wilde, S. Dalal · RFC 9457 · July 2023 · obsoletes RFC 7807 · §3.1, §3.2, §4.2, §5
API deprecation and retirement
An integration can remain available after being deprecated. Planning migration therefore requires separating the announced lifecycle, actual service state and dependencies still to move. This dossier adds relevant HTTP signals, deadline interpretation and exit checks for API, operations and security teams.
References: RFC 9745 (March 2025) for Deprecation and RFC 8594 (May 2019, Informational) for Sunset. When both dates are provided, Sunset must not precede Deprecation. Equal dates satisfy that ordering; they do not establish that sufficient notice was provided.
IETF · RFC 9745 · Deprecation · Standards Track · March 2025 · §2–5 · consulted 2026-10-23
IETF · RFC 8594 · Sunset · Informational · May 2019 · §3–5, §8 · consulted 2026-10-23
Four signals for planning migration
| Signal | What it communicates | Format or nature | Limitation to retain |
|---|---|---|---|
Deprecation | Announces past or future deprecation of the contextual resource. | Structured Fields Date, not a textual HTTP-date. | Does not by itself change resource behaviour. |
Sunset | Indicates when the resource is likely to stop responding. | HTTP-date; emitted IMF-fixdate uses GMT. | A retirement hint, not an availability guarantee before or after. |
Link · rel="deprecation" | Points to deprecation documentation. | A link relation, not a date. | Documentation may be exposed before a dated announcement. |
Link · rel="sunset" | Points to retirement information or policy. | A link relation, not a deadline. | Read the scope and conditions actually documented. |
Two date formats that must not be interchanged
| Educational example | Reading | Reference |
|---|---|---|
| Deprecation: @1688169599 | 30 June 2023 at 23:59:59 UTC. The number represents seconds since the Unix epoch, prefixed with @. | RFC 9745 §2.1; RFC 9651 §3.3.7 |
| Sunset: Sun, 30 Jun 2024 23:59:59 GMT | CIE example in IMF-fixdate: English weekday, date and GMT. Do not substitute an ISO timestamp here. | RFC 8594 §3; RFC 9110 §5.6.7 |
IETF · RFC 9651 · Structured Fields · Standards Track · September 2024 · §3.3.7 · consulted 2026-10-23
IETF · RFC 9110 · HTTP semantics · Internet Standard · June 2022 · §5.6.7 · consulted 2026-10-23
Read a UTC timeline
Compare timestamps already normalised to UTC. The reader does not decode HTTP headers: it works on dates you have extracted and checked. Both deadlines are optional; the reading timestamp is required. Examples use a fixed reference time so results remain reproducible.
CIE input profile: YYYY-MM-DDTHH:mm:ssZ, years 1970 to 2099, seconds 00 to 59, without fractions, spaces or numeric offsets. These limits keep the workshop predictable; they do not describe the full RFC syntax. A blank date means “not supplied in this exercise”, not “this policy does not exist”.
Local calculation without network requests, import, storage or export. The reader establishes neither availability, compatibility nor complete header conformance. It derives no minimum migration notice: check the contract, policy, dependencies and provider contact. Reaching a Sunset date remains an announced hint, not proof of actual shutdown.
Deadline offsets from the reading time are signed: negative means past, zero means reached, positive means future. Sunset − Deprecation compares the announcements; a negative interval signals inconsistent ordering. Values are exact seconds within the profile, not local calendar days.
UTC format YYYY-MM-DDTHH:mm:ssZ, years 1970–2099. Deadlines optional; reading timestamp required.
Result
Nine reading scenarios, available without JavaScript
V01 · Future deprecation
| Normalised Deprecation | Normalised Sunset | UTC reading timestamp | Expected reading |
|---|---|---|---|
| 2026-11-01T00:00:00Z | 2026-12-01T00:00:00Z | 2026-10-23T00:00:00Z | Two future deadlines separated by 2,592,000 seconds. This timeline does not establish contractually sufficient notice. |
V02 · Deprecation already effective
| Normalised Deprecation | Normalised Sunset | UTC reading timestamp | Expected reading |
|---|---|---|---|
| 2026-10-01T00:00:00Z | 2026-12-01T00:00:00Z | 2026-10-23T00:00:00Z | Deprecation is past and Sunset is future. This does not mean the resource has already stopped working. |
V03 · Sunset date reached
| Normalised Deprecation | Normalised Sunset | UTC reading timestamp | Expected reading |
|---|---|---|---|
| 2026-10-01T00:00:00Z | 2026-10-23T00:00:00Z | 2026-10-23T00:00:00Z | Sunset minus reading time is zero. Check actual service state and migration; the field remains a hint. |
V04 · Conflicting order
| Normalised Deprecation | Normalised Sunset | UTC reading timestamp | Expected reading |
|---|---|---|---|
| 2026-11-01T00:00:00Z | 2026-10-01T00:00:00Z | 2026-10-23T00:00:00Z | Sunset precedes Deprecation by 2,678,400 seconds. Seek clarification rather than assuming a coherent schedule. |
V05 · Sunset only
| Normalised Deprecation | Normalised Sunset | UTC reading timestamp | Expected reading |
|---|---|---|---|
| — | 2026-12-01T00:00:00Z | 2026-10-23T00:00:00Z | A retirement date is supplied, but no Deprecation date is provided in the exercise. Do not invent the missing date. |
V06 · Deprecation only
| Normalised Deprecation | Normalised Sunset | UTC reading timestamp | Expected reading |
|---|---|---|---|
| 2026-10-01T00:00:00Z | — | 2026-10-23T00:00:00Z | Deprecation is effective at the chosen time; no retirement date is supplied. Do not infer a support period. |
V07 · No deadlines supplied
| Normalised Deprecation | Normalised Sunset | UTC reading timestamp | Expected reading |
|---|---|---|---|
| — | — | 2026-10-23T00:00:00Z | The absence of dates in this input guarantees neither longevity nor the absence of an external policy. |
V08 · Impossible calendar date
| Normalised Deprecation | Normalised Sunset | UTC reading timestamp | Expected reading |
|---|---|---|---|
| 2026-02-29T00:00:00Z | 2026-12-01T00:00:00Z | 2026-10-23T00:00:00Z | 2026 is not a leap year. Input is rejected instead of silently normalising into March. |
V09 · Both dates equal the reading time
| Normalised Deprecation | Normalised Sunset | UTC reading timestamp | Expected reading |
|---|---|---|---|
| 2026-10-23T00:00:00Z | 2026-10-23T00:00:00Z | 2026-10-23T00:00:00Z | Ordering satisfies the non-earlier relation with a zero interval. This does not establish that a migration period was offered. |
Collect evidence for a controlled exit
| Suggested check | Verifiable record |
|---|---|
| Scope | Affected resource, operations, version, environment and policy; do not generalise one response to every route. |
| Consumers | Owners, SDKs, scheduled jobs and partner integrations; reconcile declared inventory and observed use. |
| Timeline | Announcement origin, UTC dates, updates and authorised provider contact. |
| Replacement | Test existing journeys on the target: data, permissions, errors, pagination and side effects. |
| Coexistence | Cutover criterion, rollback strategy and treatment of in-flight or replayed operations. |
| Closure | Check remaining consumers, remove obsolete secrets, update documentation and verify the business outcome. |
A useful alert connects a deadline to a consumer and a verifiable action. Record what was announced, what was actually tested and what remains unknown. If dates conflict, ask the provider for clarification before turning the timeline into a cutover schedule.
Sources, editions and credits
Original CIE summaries informed by RFCs 9745, 8594, 9651 and 9110. Fictional educational scenarios and checks. The comparison program is original; no RFC algorithm is reproduced. The second date example is written by CIE using GMT, following HTTP’s emission format.
IETF · RFC 9745 · Deprecation · Standards Track · March 2025 · §2–5 · consulted 2026-10-23
SHA-256 : 84d1c7e47062f92b08f12e83eee258c59cf6adef970fae938d92c30fa0a0411f
IETF · RFC 8594 · Sunset · Informational · May 2019 · §3–5, §8 · consulted 2026-10-23
SHA-256 : 1a20d634f9cb1d68295b5c501d32c68f43799dfbdb1e8b4ac21707b8c273aa80
IETF · RFC 9651 · Structured Fields · Standards Track · September 2024 · §3.3.7 · consulted 2026-10-23
SHA-256 : fe27f2ec8819911afbe4bd11f6fcb947580da4c49e5423a1fff960e252ced26d
IETF · RFC 9110 · HTTP semantics · Internet Standard · June 2022 · §5.6.7 · consulted 2026-10-23
SHA-256 : 21c1cdce6ab0e5509b04d84a28000836c7a087cf786efe6f04877ebfff47232a
Official references
References consulted: . The method and worksheet propose checks to adapt to your context; they do not constitute certification.
- AWS Builders’ Library — safe retries and idempotent APIs
- Google Cloud — scalable and resilient apps
- OASIS · TAXII 2.1
- IETF · RFC 9110 — HTTP Semantics
- IETF · RFC 9111 — HTTP Caching
- IETF · RFC 6585 — Additional HTTP Status Codes
- IETF · RFC 9700 · OAuth 2.0 Security BCP
- IETF · RFC 9068 · JWT access token profile
- OpenID Foundation · OpenID Connect Core 1.0
- IETF · RFC 8725 · JWT Best Current Practices
- IETF · RFC 6749 · OAuth 2.0 framework
- Stripe · Webhooks
- Stripe · Manage webhook endpoints
- GitHub · Validating webhook deliveries
- GitHub · Best practices for using webhooks
- GitHub · Handling failed webhook deliveries
- OWASP · SSRF Prevention Cheat Sheet
- WHATWG · URL Living Standard
- AWS EC2 · Instance metadata options
- IETF · RFC 3849
- Google · AIP-158 Pagination
- PostgreSQL 18 · LIMIT and OFFSET
- PostgreSQL 18 · Row constructor comparison
- PostgreSQL 18 · Transaction isolation
- OWASP · API1:2023 Broken Object Level Authorization
- IETF · RFC 9745 · Deprecation
- IETF · RFC 8594 · Sunset
- IETF · RFC 9651 · Structured Fields
- IETF · M. Nottingham, E. Wilde, S. Dalal · RFC 9457
- AWS Builders’ Library · Timeouts, retries, and backoff with jitter
- Stripe · Idempotent requests
- Stripe · API v2 overview — Idempotency
- Stripe · Advanced error handling
