0.0
The project is in a healthy, maintained state
A Sinatra extension wrapping the UniRate API (https://unirateapi.com) — free currency exchange rates, conversion, supported-currency listings, and VAT rates. Registers via `register Sinatra::UniRate` in classic or modular apps, exposes settings-based configuration, route/view helpers (unirate_rate, unirate_convert, unirate_currencies, unirate_vat), an optional JSON proxy mount, and a stdlib-only client with full error mapping. Zero runtime dependencies beyond Sinatra.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

>= 2.0
~> 13.0
~> 3.12
~> 1.60
~> 3.19

Runtime

>= 2.0
 Project Readme

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.

Related clients

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.