Skip to content

Repository files navigation

@unirate/core

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 fetch exists — Deno, Node.js 18+, Bun, and browsers
  • 📦 Zero dependencies

Installation

Deno

deno add jsr:@unirate/core

Or import straight from JSR:

import { UnirateClient } from "jsr:@unirate/core";

Node.js / Bun

npx jsr add @unirate/core

Then import as usual:

import { UnirateClient } from "@unirate/core";

Quick start

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.

API

Current rates

// 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 data (Pro-gated)

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();

VAT rates

// All countries
const vatRates = await client.getVATRates();

// Single country (ISO-3166 alpha-2 code)
const germany = await client.getVATRates("DE");

Output formats

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");

Error handling

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

Advanced — dependency injection

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,
});

Rate limits

  • Currency endpoints: standard rate limits apply
  • Historical endpoints: 50 requests/hour on the free tier
  • VAT endpoints: 1800 requests/hour on the free tier

Related clients

License

MIT — see LICENSE.

About

Official cross-runtime TypeScript client for the UniRate API — free currency exchange & VAT rates. Published on JSR as @unirate/core.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages