# `Tipalti.RateLimiter`
[🔗](https://github.com/iamkanishka/tipalti/blob/main/lib/tipalti/rate_limiter.ex#L1)

An optional, self-contained token-bucket rate limiter.

Tipalti's Procurement API documents explicit limits (purchase-order
updates around 5 requests/minute; reads no more often than every 10
minutes). The HTTP layer already retries a 429 with backoff, but for
high-throughput integrations it's often better to avoid tripping the
limit at all — start one of these per limited operation and call
`take/2` before issuing a request.

    {:ok, _pid} = Tipalti.RateLimiter.start_link(name: :po_updates, rate: 5, per: :timer.minutes(1))
    :ok = Tipalti.RateLimiter.take(:po_updates)
    Tipalti.Procurement.PurchaseOrders.update(config, attrs)

Not started automatically and not required — every other module in this
package works without one.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts a rate limiter allowing `rate` operations per `per` milliseconds,
registered under `name`.

# `take`

```elixir
@spec take(GenServer.name(), timeout()) :: :ok | {:error, :timeout}
```

Blocks the caller until a token is available, then consumes it. Returns
`:ok`. Uses a naive poll/sleep loop bounded by `timeout` (default 60s);
returns `{:error, :timeout}` if no token becomes available in time.

---

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