# `Money.ExchangeRates.Retriever`
[🔗](https://github.com/ex-money/money/blob/v6.1.1/lib/money/exchange_rates/retriever.ex#L1)

A `GenServer` that retrieves exchange rates from a configured API module on a
periodic or on-demand basis.

Add it to your application's supervision tree to enable the exchange rates
service:

    children = [
      MyApp.Repo,
      Money.ExchangeRates.Retriever
    ]

To start with a custom configuration:

    children = [
      {Money.ExchangeRates.Retriever, [config: my_config]}
    ]

Multiple named retrievers can be started independently, each backed by a
different API source:

    children = [
      {Money.ExchangeRates.Retriever, [name: :open_exchange_rates, config: oxr_config]},
      {Money.ExchangeRates.Retriever, [name: :fixer, config: fixer_config]}
    ]

    Money.ExchangeRates.Retriever.latest_rates(:open_exchange_rates)
    Money.ExchangeRates.Retriever.historic_rates(:fixer, ~D[2024-01-01])

> #### Each named retriever needs its own cache module {: .warning}
>
> The bundled cache implementations (`Money.ExchangeRates.Cache.Ets` and
> `Money.ExchangeRates.Cache.Dets`) use a fixed, module-wide storage location
> (the `:exchange_rates` ETS table / a single DETS file). Two retrievers
> configured with the same `cache_module` therefore share one cache and will
> overwrite each other's rates. When running multiple named retrievers, give
> each its own `cache_module` (a distinct module backed by a distinct ETS
> table name or DETS path) in its configuration.

By default exchange rates are retrieved from
[Open Exchange Rates](http://openexchangerates.org). The retrieval interval
is configured via the `:exchange_rates_retrieve_every` key (milliseconds):

    config :ex_money,
      exchange_rates_retrieve_every: 300_000

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `config`

Returns the current configuration of the Exchange Rates
Retrieval service

# `delete`

> This function is deprecated. Use `Supervisor.delete_child/2` on your application's supervisor instead.

# `historic_rates`

```elixir
@spec historic_rates(Calendar.date()) ::
  {:ok, map()} | {:error, {Exception.t(), binary()}}
@spec historic_rates(Date.Range.t()) ::
  [ok: map(), error: {Exception.t(), binary()}]
  | {:error, {Exception.t(), binary()}}
```

Forces retrieval of historic exchange rates for a single date

* `date` is a `t:Date.t/0` or any date-compatible map or struct (`t:Calendar.date/0`) or

* a `Date.Range.t` created by `Date.range/2` that specifies a
  range of dates to retrieve

Returns:

* `{:ok, rates}` if exchange rates request is successfully sent.

* `{:error, reason}` if the request cannot be sent.

Sends a message to the exchange rate retrieval worker to request
historic rates for a specified date or range be retrieved and
stored.

This function does not return exchange rates, for that see
`Money.ExchangeRates.latest_rates/0` or
`Money.ExchangeRates.historic_rates/1`.

# `historic_rates`

```elixir
@spec historic_rates(GenServer.server(), Calendar.date()) ::
  {:ok, map()} | {:error, {Exception.t(), binary()}}
@spec historic_rates(GenServer.server(), Date.Range.t()) ::
  [ok: map(), error: {Exception.t(), binary()}]
  | {:error, {Exception.t(), binary()}}
@spec historic_rates(Calendar.date(), Calendar.date()) ::
  [ok: map(), error: {Exception.t(), binary()}]
  | {:error, {Exception.t(), binary()}}
```

Forces retrieval of historic exchange rates for a range of dates

* `from` is a `t:Date.t/0` or any date-compatible map or struct (`t:Calendar.date/0`).

* `to` is a `t:Date.t/0` or any date-compatible map or struct (`t:Calendar.date/0`).

Returns:

* `{:ok, rates}` if exchange rates request is successfully sent.

* `{:error, reason}` if the request cannot be sent.

Sends a message to the exchange rate retrieval process for each
date in the range `from`..`to` to request historic rates be
retrieved.

# `historic_rates`

```elixir
@spec historic_rates(GenServer.server(), Calendar.date(), Calendar.date()) ::
  [ok: map(), error: {Exception.t(), binary()}]
  | {:error, {Exception.t(), binary()}}
```

# `last_updated`

```elixir
@spec last_updated(GenServer.server()) ::
  {:ok, DateTime.t()} | {:error, {Exception.t(), binary()}}
```

Returns the timestamp of the last successful exchange rate retrieval.

Returns:

* `{:ok, datetime}` if rates have been retrieved at least once.

* `{:error, reason}` if the retriever is not running or no retrieval has
  occurred yet.

# `latest_rates`

```elixir
@spec latest_rates(GenServer.server()) ::
  {:ok, map()} | {:error, {Exception.t(), binary()}}
```

Forces retrieval of the latest exchange rates

Sends a message to the exchange rate retrieval worker to request
current rates be retrieved and stored.

Returns:

* `{:ok, rates}` if exchange rates request is successfully sent.

* `{:error, reason}` if the request cannot be sent.

This function does not return exchange rates, for that see
`Money.ExchangeRates.latest_rates/0` or
`Money.ExchangeRates.historic_rates/1`.

# `latest_rates_available?`

```elixir
@spec latest_rates_available?(GenServer.server()) :: boolean()
```

Returns `true` if the latest exchange rates are available in the cache,
`false` otherwise.

Returns `false` when the retriever is not running, even if the cache table
still exists.

# `reconfigure`

Updates the configuration for the Exchange Rate
Service

# `restart`

> This function is deprecated. Use `Supervisor.restart_child/2` on your application's supervisor instead.

# `retrieve_rates`

> This function is deprecated. Use `Money.ExchangeRates.HTTP` or the HTTP client of your preference directly instead.

# `start`

> This function is deprecated. Use `Supervisor.start_child/2` on your application's supervisor instead.

# `stop`

> This function is deprecated. Use `Supervisor.terminate_child/2` on your application's supervisor instead.

---

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