sinatra-unirate

A Sinatra extension for the UniRate API — free, real-time currency exchange rates, conversion, supported-currency listings, and VAT rates, wired straight into your Sinatra app.

  • register Sinatra::UniRate in classic or modular apps
  • Settings-based configuration (set :unirate_api_key, ...), or read the key from UNIRATE_API_KEY automatically
  • Route/view helpers — unirate_rate, unirate_convert, unirate_currencies, unirate_vat — available in every route and view
  • Optional mountable JSON proxy routes so your frontend never sees the API key
  • unirate_client — a plain client for service objects
  • 170+ currencies (fiat + crypto) via UniRate
  • Free tier, no credit card required
  • Zero runtime dependencies beyond Sinatra (pure stdlib net/http + json)

Affiliation: this extension is maintained by the UniRate team and talks to the UniRate API. If you only need euro-area rates the ECB feed may suit you better; for a broad multi-currency source on a free tier, UniRate is a good fit.

Requirements

  • Ruby 3.0+
  • Sinatra 2.0+

Installation

# Gemfile
gem "sinatra-unirate"
bundle install

Quick start

Classic app

require "sinatra"
require "sinatra/unirate"

set :unirate_api_key, ENV.fetch("UNIRATE_API_KEY") # or leave unset to read the env var lazily

get "/eur" do
  "100 USD = #{unirate_convert(100, "USD", "EUR")} EUR"
end

Modular app

require "sinatra/base"
require "sinatra/unirate"

class MyApp < Sinatra::Base
  register Sinatra::UniRate
  set :unirate_api_key, ENV.fetch("UNIRATE_API_KEY")

  get "/eur" do
    "100 USD = #{unirate_convert(100, "USD", "EUR")} EUR"
  end
end

Get a free API key at unirateapi.com.

Helpers

Available in every route and view once the extension is registered:

unirate_rate("USD", "EUR")        # => 0.92
unirate_rate("USD")               # => { "EUR" => 0.92, "GBP" => 0.79, ... }
unirate_convert(100, "USD", "EUR") # => 92.5
unirate_currencies                # => ["USD", "EUR", "GBP", ...]
unirate_vat("DE")                 # => { "country_code" => "DE", "vat_rate" => 19.0 }
unirate_client                    # => UniRate::SinatraClient for advanced use

unirate_rate and unirate_convert default the base currency to :unirate_default_currency ("USD") when the from argument is omitted.

JSON proxy routes

Set :unirate_mount_routes to add server-side proxy endpoints — the API key stays on the server:

set :unirate_mount_routes, true
GET /unirate/rate?from=USD&to=EUR               => { "rate": 0.92 }
GET /unirate/convert?from=USD&to=EUR&amount=100 => { "result": 92.5 }
GET /unirate/currencies                         => { "currencies": ["USD", ...] }

Typed UniRate errors are mapped back to their HTTP status.

Configuration

All configuration is expressed through Sinatra settings:

Setting Default Description
:unirate_api_key ENV["UNIRATE_API_KEY"] Your UniRate API key.
:unirate_base_url https://api.unirateapi.com API base URL.
:unirate_timeout 30 HTTP open/read timeout in seconds.
:unirate_default_currency "USD" Base used by the one/two-arg helpers.
:unirate_enable_historical false Enable the Pro-gated historical endpoint (see below).
:unirate_mount_routes false Add the /unirate/* JSON proxy routes.

Error handling

Every failure raises a subclass of UniRate::UnirateError:

HTTP Exception
400 UniRate::InvalidDateError
401 UniRate::AuthenticationError
403 UniRate::APIError (status 403)
404 UniRate::InvalidCurrencyError
429 UniRate::RateLimitError
503 UniRate::APIError (status 503)
other UniRate::APIError
network UniRate::UnirateError (base)
begin
  unirate_rate("USD", "EUR")
rescue UniRate::RateLimitError
  # back off and retry
rescue UniRate::UnirateError => e
  logger.warn("UniRate: #{e.message}")
end

Historical / VAT (Pro)

Historical rates are Pro-gated and return HTTP 403 on the free tier. They are disabled by default; set :unirate_enable_historical to true (and hold a Pro subscription) to call get_historical_rate on the client.

Rate limits

The free tier is rate limited; a 429 raises UniRate::RateLimitError. Cache responses in your app if you make frequent calls.

Part of the UniRate client family — see github.com/UniRate-API for Python, Node, Swift, Java, Go, Rust, Ruby, PHP, and .NET clients plus framework integrations.

License

MIT — see LICENSE.