# `BankingCircle.HTTP.Middleware.Retry`
[🔗](https://github.com/iamkanishka/banking_circle/blob/main/lib/banking_circle/http/middleware/retry.ex#L1)

Configures Req's built-in retry mechanism with Banking-Circle-appropriate
policy: capped exponential backoff with full jitter, honoring a
server-provided `Retry-After` when present (notably on 429s from the auth
and payment endpoints).

Rather than hand-rolling request/response steps against Req's internals,
this module builds the `:retry`, `:retry_delay`, and `:max_retries`
options that Req's own retry step already understands — this keeps us
aligned with upstream Req behavior across version bumps instead of
reimplementing it.

## Retry policy

  * `GET`/`HEAD` requests are always eligible (safe by HTTP semantics).
  * Other methods are only eligible if the request carries an
    `idempotency-key` header — Banking Circle only guarantees idempotency
    on endpoints that support that header today (Direct Debit Collections
    at time of writing). A bare `POST` without one is **never**
    auto-retried, to avoid duplicate payment submission.
  * Eligible statuses: 429, 500, 502, 503, 504.
  * Eligible transport errors: timeout, closed, econnrefused, econnreset.

# `options`

```elixir
@spec options(BankingCircle.Config.t()) :: keyword()
```

Returns Req options implementing the policy above. Merge these into a
`Req.new/1` call, e.g. `Req.new([...] ++ Retry.options(config))`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
