# `TruelayerClient.Idempotency`
[🔗](https://github.com/iamkanishka/truelayer_client/blob/v1.0.0/lib/truelayer_client/idempotency.ex#L1)

Thread-safe idempotency key manager backed by ETS.

The same `operation_id` always yields the same key until `release/2` is
called, ensuring POST retries always send an identical `Idempotency-Key`
header — preventing duplicate payments or payouts.

Each `TruelayerClient` instance owns a separate ETS table created at
construction time, so multiple clients on the same node are fully isolated.

# `table`

```elixir
@type table() :: :ets.tid()
```

# `key_for`

```elixir
@spec key_for(table(), String.t()) :: String.t()
```

Return the idempotency key for `operation_id`.

Creates a new UUID-shaped key on first call and returns the same key on
every subsequent call with the same `operation_id` (until `release/2`).
Safe to call concurrently from multiple processes.

# `new_key`

```elixir
@spec new_key() :: String.t()
```

Generate a random UUID v4-shaped key using `:crypto.strong_rand_bytes/1`.

# `new_table`

```elixir
@spec new_table() :: table()
```

Create a new ETS table for idempotency keys. Called once per client.

# `release`

```elixir
@spec release(table(), String.t()) :: :ok
```

Remove the stored key for `operation_id` after a confirmed successful response.

Subsequent calls to `key_for/2` with the same `operation_id` will generate
a fresh key, making re-use of operation IDs safe after confirmed success.

---

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