# `BankingCircle.Auth.TokenServer`
[🔗](https://github.com/iamkanishka/banking_circle/blob/main/lib/banking_circle/auth/token_server.ex#L1)

Caches a Banking Circle OAuth2 JWT per configured client and refreshes it
transparently, following Banking Circle's documented guidance:

  * Tokens live ~5 minutes.
  * Callers should reuse a token until it's actually (about to be) expired,
    not fetch a new one per request — Banking Circle rate-limits the auth
    endpoint per IP per minute, and naive per-call fetching trips it fast.

## Single-flight refresh

All `fetch/1` calls for a given client go through this one GenServer, so
concurrent callers racing a near-simultaneous expiry collapse into a
single outbound authorization request rather than a stampede — the
GenServer mailbox naturally serializes it.

One `TokenServer` is started per configured client name under
`BankingCircle.Auth.Supervisor`.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `fetch`

```elixir
@spec fetch(atom()) ::
  {:ok, BankingCircle.Auth.Token.t()} | {:error, BankingCircle.Error.t()}
```

Returns a valid (non-expiring-soon) token for the given client, refreshing
it first if necessary.

# `invalidate`

```elixir
@spec invalidate(atom()) :: :ok
```

Forces a refresh on the next `fetch/1`, discarding any cached token.

# `start_link`

```elixir
@spec start_link(BankingCircle.Config.t()) :: GenServer.on_start()
```

---

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