Official cross-runtime TypeScript client for the UniRate API — free, real-time and historical currency exchange rates plus VAT rates. Published on JSR.
- 🔄 Real-time exchange rates between 170+ currencies (fiat + crypto)
- 📈 Historical rates back to 1999
- ⏰ Time-series ranges up to 5 years
- 💰 Currency conversion (current and historical)
- 🏛️ VAT rates for countries worldwide
- 🆓 Free tier, no credit card required
- ⚡ Modern TypeScript:
async/await, fully typed,fetch-based - 🌍 Runs anywhere
fetchexists — Deno, Node.js 18+, Bun, and browsers - 📦 Zero dependencies
deno add jsr:@unirate/coreOr import straight from JSR:
import { UnirateClient } from "jsr:@unirate/core";npx jsr add @unirate/coreThen import as usual:
import { UnirateClient } from "@unirate/core";import { UnirateClient } from "@unirate/core";
const client = new UnirateClient("your-api-key");
// Current rate
const rate = await client.getRate("USD", "EUR");
console.log(`USD -> EUR: ${rate}`);
// Convert an amount
const euros = await client.convert("EUR", 100, "USD");
console.log(`100 USD = ${euros} EUR`);
// All supported currencies
const currencies = await client.getSupportedCurrencies();
if (Array.isArray(currencies)) {
console.log(`${currencies.length} currencies supported`);
}Get a free API key at https://unirateapi.com.
// Single pair -> number
const rate = await client.getRate("USD", "EUR");
// All rates for a base -> Record<string, number>
const rates = await client.getRate("USD");
// Convert an amount -> number
const result = await client.convert("EUR", 100, "USD");
// Supported currency list -> string[]
const codes = await client.getSupportedCurrencies();Historical endpoints require a Pro subscription and return HTTP 403 on the free
tier (surfaced as an APIError with statusCode === 403).
// Rate on a specific date
const rate = await client.getHistoricalRate("2024-01-01", 1, "USD", "EUR");
// All rates on a date
const rates = await client.getHistoricalRates("2024-01-01", 1, "USD");
// Convert using a historical rate
const amount = await client.convertHistorical(100, "USD", "EUR", "2024-01-01");
// Time series (max 5 years)
const series = await client.getTimeSeries(
"2024-01-01",
"2024-01-07",
1,
"USD",
["EUR", "GBP"],
);
// Available historical coverage per currency
const limits = await client.getHistoricalLimits();// All countries
const vatRates = await client.getVATRates();
// Single country (ISO-3166 alpha-2 code)
const germany = await client.getVATRates("DE");Every method accepts optional format ("json" | "xml" | "csv" | "tsv")
and callback (JSONP) arguments. When format is not "json", the raw
response body is returned as a string:
const csv = await client.getRate("USD", "EUR", "csv");All errors inherit from UnirateError, so one catch covers every failure:
import {
APIError,
AuthenticationError,
InvalidCurrencyError,
InvalidDateError,
RateLimitError,
UnirateError,
} from "@unirate/core";
try {
const rate = await client.getRate("USD", "ZZZ");
} catch (error) {
if (error instanceof AuthenticationError) {
// invalid API key (401)
} else if (error instanceof InvalidCurrencyError) {
// unknown currency code (404)
} else if (error instanceof RateLimitError) {
// back off and retry (429)
} else if (error instanceof InvalidDateError) {
// bad request parameters (400)
} else if (error instanceof APIError) {
// other HTTP error — inspect error.statusCode (e.g. 403 Pro-gated, 503)
} else if (error instanceof UnirateError) {
// transport / network failure
}
}| Status | Error type |
|---|---|
| 400 | InvalidDateError |
| 401 | AuthenticationError |
| 403 | APIError (Pro-gated) |
| 404 | InvalidCurrencyError |
| 429 | RateLimitError |
| 503 | APIError |
| other | APIError |
The client accepts a custom fetch implementation, which makes mocking trivial
in tests and lets you plug in a proxy or instrumented client:
const client = new UnirateClient("test-key", {
timeout: 10_000,
baseUrl: "https://api.unirateapi.com",
fetch: myCustomFetch,
});- Currency endpoints: standard rate limits apply
- Historical endpoints: 50 requests/hour on the free tier
- VAT endpoints: 1800 requests/hour on the free tier
- unirate-api-python — Python (PyPI:
unirate-api) - unirate-api-nodejs — Node.js / TypeScript (npm:
unirate-api) - unirate-api-go — Go
- unirate-api-rust — Rust (crates.io:
unirate-api) - unirate-api-swift — Swift (SPM)
- unirate-api-java — Java (Maven)
- unirate-api-ruby — Ruby (gem:
unirate-api) - unirate-api-php — PHP (Composer:
unirate-api/unirate-api) - unirate-api-dotnet — .NET / C# (NuGet:
UniRateApi)
MIT — see LICENSE.