Powrót do bloga

Currency Pairs Explained: Major, Minor, and Exotic Pairs (Developer's Guide)

V
Vlado Grigirov
April 26, 2026
Currency API Exchange Rates Forex Currency Pairs Developer Guide Finexly Education

Currency Pairs Explained: Major, Minor, and Exotic Pairs (Developer's Guide)

If you are building anything that touches international money — a checkout, a fintech dashboard, a trading bot, a treasury tool, even a simple currency converter — you will run into the concept of currency pairs within your first hour of work. Pairs are the unit of measurement in foreign exchange (FX): a single currency has no price by itself, only relative to another currency. Understanding how pairs are classified, quoted, and handled in code is the foundation for every other FX feature you will ever build.

This guide explains major, minor, and exotic currency pairs from a developer's perspective. We will cover what each category means, the conventions you have to respect when reading or writing pair strings, and the practical patterns for fetching, normalizing, and calculating with pairs through the Finexly API documentation. By the end you will know which pairs to support first, how to handle the edge cases, and how to pull live rates with a few lines of code.


What Is a Currency Pair?

A currency pair is a quote that expresses the price of one currency in terms of another. It is always written with two ISO 4217 codes — for example EUR/USD or EURUSD — and a single decimal price.

The first currency in the pair is the base currency. The second is the quote currency (sometimes called the counter currency). The price tells you how many units of the quote currency it takes to buy one unit of the base.

So EUR/USD = 1.0850 means one euro is worth 1.0850 US dollars. If the quote rises to 1.0900, the euro has strengthened against the dollar. If it falls to 1.0800, the euro has weakened. The base currency is the "thing being priced," and the quote currency is the "money you pay with."

This is a simple convention, but it trips up almost every developer at least once. If you store rates without consistently tracking which side is the base and which is the quote, you will eventually invert a number and silently overcharge or undercharge a user. We will cover how to avoid this in the code section below. For a deeper primer on what drives the price itself, see our guide on how exchange rates work.

The global FX market trades around $7.5 trillion per day, according to the Bank for International Settlements' triennial survey, making it the largest financial market in the world. That liquidity is not spread evenly across pairs — most of it concentrates in a small group of pairs called the majors.


Major Currency Pairs

Major pairs are the most heavily traded currency pairs in the world. The market does not have a single official definition, but in practice every major pair has two properties: it includes the US dollar (USD) on one side, and the other side is a currency from a large, stable, developed economy.

There are seven pairs almost universally accepted as the majors:

  • EUR/USD — Euro / US Dollar
  • USD/JPY — US Dollar / Japanese Yen
  • GBP/USD — British Pound / US Dollar
  • USD/CHF — US Dollar / Swiss Franc
  • AUD/USD — Australian Dollar / US Dollar
  • USD/CAD — US Dollar / Canadian Dollar
  • NZD/USD — New Zealand Dollar / US Dollar

Together, the majors account for roughly 75% of global FX volume, with EUR/USD alone responsible for around a quarter of all trading. This concentration has direct consequences for anything you build:

  • Tightest spreads. The gap between the bid (what buyers pay) and the ask (what sellers want) is smallest on majors. If you are showing rates to end users, this means the smallest gap between the mid-market exchange rate and what they will actually receive.
  • Highest update frequency. Tick data on majors arrives many times per second during market hours. Minor and exotic pairs update more sporadically.
  • Most reliable historical data. If you are backtesting, building analytics, or charting, majors will have the cleanest, longest, gap-free histories.
  • Lowest API cost per useful answer. Because one major pair often serves as a building block for dozens of other rates (via cross-rate calculation), you can often serve a global product by caching the majors aggressively and deriving the rest.

Here is a minimal example of pulling all seven majors from Finexly in one request:

// Fetch all major pairs vs USD in a single call
const symbols = ['EUR', 'JPY', 'GBP', 'CHF', 'AUD', 'CAD', 'NZD'];

const response = await fetch(
  `https://api.finexly.com/v1/latest?base=USD&symbols=${symbols.join(',')}`,
  { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);

const data = await response.json();
console.log(data.rates);
// { EUR: 0.9217, JPY: 154.32, GBP: 0.7891, CHF: 0.8843, ... }

Notice that we requested base=USD and got back rates for each symbol in terms of USD. To get the conventional pair direction (for example EUR/USD rather than USD/EUR), you may need to invert. We cover that pattern in the code section below.


Minor (Cross) Currency Pairs

Minor pairs, also called crosses or cross currency pairs, are pairs of two major currencies that do not include the US dollar. The name "cross" comes from the fact that historically these pairs had to be calculated by "crossing" two USD pairs — for example, deriving EUR/GBP from EUR/USD and GBP/USD. Today most APIs and brokers quote them directly, but the underlying math is still useful to understand.

Common minor pairs include:

  • EUR/GBP — Euro / British Pound
  • EUR/JPY — Euro / Japanese Yen
  • EUR/CHF — Euro / Swiss Franc
  • GBP/JPY — British Pound / Japanese Yen
  • AUD/JPY — Australian Dollar / Japanese Yen
  • CHF/JPY — Swiss Franc / Japanese Yen
  • EUR/AUD — Euro / Australian Dollar
  • GBP/CAD — British Pound / Canadian Dollar

Crosses still have strong liquidity — especially the EUR and JPY crosses — but spreads are typically wider than on the seven majors and intraday volatility is often higher. GBP/JPY, for example, is famous among traders for moving aggressively, which is why it is sometimes called "the dragon."

For developers, the practical implication is that you should not assume an exotic-grade markup or an exotic-grade update cadence on every non-USD pair. Crosses sit in the middle: good enough liquidity for almost any consumer or B2B product, but not the same razor-thin spread as EUR/USD.

If your provider does not quote a particular cross directly, you can always derive it from the two USD legs:

# Derive EUR/GBP from EUR/USD and GBP/USD
eur_usd = 1.0850   # 1 EUR = 1.0850 USD
gbp_usd = 1.2680   # 1 GBP = 1.2680 USD

# 1 EUR = (eur_usd / gbp_usd) GBP
eur_gbp = eur_usd / gbp_usd
print(f"EUR/GBP = {eur_gbp:.4f}")  # EUR/GBP = 0.8557

This is exactly what most rate engines do behind the scenes. Finexly returns crosses directly via the currency converter endpoint, but the math above is good to keep in your head: it lets you spot-check any rate, and it lets you fall back gracefully if a particular pair is missing from a feed.


Exotic Currency Pairs

Exotic pairs combine a major currency (typically USD or EUR) with the currency of a smaller, emerging-market, or less-liquid economy. Examples include:

  • USD/TRY — US Dollar / Turkish Lira
  • USD/MXN — US Dollar / Mexican Peso
  • USD/ZAR — US Dollar / South African Rand
  • USD/BRL — US Dollar / Brazilian Real
  • USD/INR — US Dollar / Indian Rupee
  • USD/THB — US Dollar / Thai Baht
  • EUR/PLN — Euro / Polish Zloty
  • EUR/HUF — Euro / Hungarian Forint
  • USD/SGD — US Dollar / Singapore Dollar
  • USD/HKD — US Dollar / Hong Kong Dollar

The line between "minor" and "exotic" is fuzzy — USD/SGD and USD/HKD are sometimes classed as minors because their economies are highly developed, while USD/CNH (offshore Chinese yuan) is sometimes classed as a major because of trade volume. The category matters less than the characteristics, which are what affect your code:

  • Wider spreads. The difference between the bid and ask can be 5–20× wider than on a major.
  • Lower liquidity off-hours. Many exotic pairs trade thinly outside the local market's business hours, so weekend or overnight rates can be stale or jumpy.
  • Higher headline-event sensitivity. Exotic currencies move sharply on local political news, central bank decisions, and capital control announcements. See our deep dive on how geopolitical events affect currency exchange rates.
  • More frequent rate gaps. A pair like USD/TRY can gap several percent over a weekend or after a single rate decision. If your invoicing or pricing logic doesn't handle this, you can end up showing a stale rate to a user for an hour after a big move.
  • Pegged or managed currencies. Some "exotic" pairs barely move at all because the central bank intervenes — USD/HKD is the classic example, held in a tight band. Your charts will look almost flat, which is correct, not a bug in your data.

If your product serves emerging markets, do not treat exotics as a footnote — they are often where the most pricing pain lives. We have a separate guide on handling currency volatility in 2026 that goes deeper on the operational patterns.


Direct, Indirect, and Inverse Quotes

Beyond major/minor/exotic, there is one more piece of vocabulary every developer needs: the difference between direct and indirect quotes.

A direct quote expresses the foreign currency in units of the local (home) currency. From a US perspective, USD/EUR = 0.92 is a direct quote — it tells a US user that one dollar buys 0.92 euros. An indirect quote flips that: EUR/USD = 1.0850 is a direct quote from a European perspective and an indirect quote from a US perspective.

Conventional FX market quoting follows historical "ranking" rules rather than user-perspective rules:

  • EUR is always the base when paired with anything else.
  • GBP is the base except against EUR.
  • AUD and NZD are the base against most things except EUR and GBP.
  • USD is the base against most others except the four currencies above.
  • JPY is almost always the quote currency.

So EUR/USD, GBP/USD, AUD/USD, USD/JPY, USD/CHF are the conventional directions — never USD/EUR. If your provider returns USD/EUR, that is a sign they are returning all rates with USD as the base, and it is your job to flip the pair when displaying it to traders or financial professionals who expect the conventional direction.

Inverting is simple math, but easy to get wrong:

// Convert USD-based rate to conventional pair direction
function toConventionalQuote(base: string, quote: string, rate: number) {
  const usdBaseFirst = ['EUR', 'GBP', 'AUD', 'NZD'];
  // If the quote currency is "stronger" by convention, flip
  if (usdBaseFirst.includes(quote)) {
    return { pair: `${quote}/${base}`, rate: 1 / rate };
  }
  return { pair: `${base}/${quote}`, rate };
}

toConventionalQuote('USD', 'EUR', 0.9217);
// → { pair: 'EUR/USD', rate: 1.0850 }

If you only show prices to end users who don't care about market convention, you can skip this entirely and quote everything from your home currency. But if you serve professional users — traders, treasurers, accountants — getting the direction right is a credibility marker.


How to Handle Currency Pairs in Code

This is where most developer bugs live. Here are the patterns we recommend, distilled from working with thousands of API integrations.

1. Always Use ISO 4217 Codes Internally

Never store currency identifiers as symbols ($, , ¥) or names ("dollar"). Store them as the three-letter ISO 4217 codesUSD, EUR, JPY. Symbols are ambiguous (the $ is used by 20+ currencies), and names are localized. ISO codes are unambiguous and language-neutral.

2. Normalize Pair Strings at the Edge

You will see pairs written as EURUSD, EUR/USD, EUR-USD, EUR_USD, and eur/usd. Pick one internal representation and normalize at the boundary of your system:

function normalizePair(input) {
  const cleaned = input.toUpperCase().replace(/[^A-Z]/g, '');
  if (cleaned.length !== 6) {
    throw new Error(`Invalid pair: ${input}`);
  }
  return {
    base: cleaned.slice(0, 3),
    quote: cleaned.slice(3, 6),
    canonical: `${cleaned.slice(0, 3)}/${cleaned.slice(3, 6)}`,
  };
}

normalizePair('eur-usd');
// → { base: 'EUR', quote: 'USD', canonical: 'EUR/USD' }

Internally, prefer the structured form ({ base, quote }) over the string. Strings are for logs and APIs; structured data is for code.

3. Convert Between Any Two Currencies via a Pivot

If you cache rates with a single base (USD is conventional), you can compute any pair on the fly:

def convert(amount, source, target, rates_in_usd):
    """
    rates_in_usd: dict like {'EUR': 0.9217, 'GBP': 0.7891, ...}
    Each value is "1 USD = X units of currency"
    """
    if source == target:
        return amount
    if source == 'USD':
        return amount * rates_in_usd[target]
    if target == 'USD':
        return amount / rates_in_usd[source]
    # Pivot through USD
    amount_in_usd = amount / rates_in_usd[source]
    return amount_in_usd * rates_in_usd[target]

# Convert 100 EUR to JPY using USD-based rates
rates = {'EUR': 0.9217, 'JPY': 154.32}
print(convert(100, 'EUR', 'JPY', rates))  # 16,743.31

This pattern lets you support 170+ currencies with a single hot cache of "USD vs everything" rates. Finexly's /v1/latest?base=USD endpoint returns exactly this shape.

4. Handle Decimal Precision Correctly

Currency pairs use different conventional precision levels: most majors quote to 4 or 5 decimal places (1.08503), while JPY pairs quote to 2 or 3 (154.32). Currencies like the Vietnamese dong have no minor units at all. Always store rates in Decimal / BigDecimal types — never floats — when calculating amounts that touch a user's balance. We cover the exact pitfalls in our Python currency API tutorial.

5. Cache Smart, Not Hard

Major pairs barely move from one second to the next during quiet markets, so you can cache them for 30–60 seconds without anyone noticing. Exotic pairs may need shorter TTLs around scheduled news. Our caching and error handling guide walks through a layered cache strategy that works for both.


Common Mistakes to Avoid

A short list of things that have burned real teams:

  • Storing only the rate without the pair direction. "1.0850" means nothing without knowing it is EUR/USD and not USD/EUR.
  • Mixing user-perspective and market-perspective quoting in the same UI. Pick one and label it clearly.
  • Treating weekend rates as live. FX markets close Friday 5 PM EST through Sunday 5 PM EST. The rate you serve on Saturday morning is Friday's close — fine for most apps, dangerous for any kind of execution. See forex market hours.
  • Hard-coding a list of "supported pairs." Use the API's symbols endpoint as the source of truth. New currencies appear (and rarely disappear) over time.
  • Rounding too early. Round at display time, not at calculation time. A four-decimal mid-market rate multiplied by a small amount can lose meaningful precision if you round mid-pipeline.

Frequently Asked Questions

How many currency pairs are there in total? With around 180 actively traded national currencies, the theoretical count of unique pairs is ~16,000 (180 × 179 / 2). In practice only a few hundred pairs trade with meaningful liquidity, and most APIs — including Finexly — expose 170+ currencies, which yields ~14,000 derivable pairs. Most products only need to support 20–50 in their UI.

What is the most traded currency pair in the world? EUR/USD is the most traded pair, accounting for roughly 22–24% of all daily forex volume. USD/JPY and GBP/USD follow it.

Is USD/EUR the same as EUR/USD? No. The numbers are mathematical inverses (USD/EUR = 1 / EUR/USD), but they are different quotes. Conventional market notation is EUR/USD. If you display USD/EUR to a finance professional, they will assume something is wrong.

Why are exotic currency pairs riskier? Exotic pairs sit on top of less-liquid markets, which means wider spreads, larger gaps after news, more sensitivity to local political events, and sometimes capital controls or central bank intervention. None of this makes them unusable — it just means your code should not assume "small spread, smooth tick stream" the way it can with majors.

Do I need a different API plan for exotic pairs? Not with Finexly. All 170+ currencies — majors, minors, and exotics — are available on every plan, including the free tier. The differences across plans are call volume, refresh frequency, and historical data depth, not pair coverage. Compare details on the pricing plans page.

How often should I refresh exchange rates? For most use cases (e-commerce display, invoicing, reporting): every 5–15 minutes is plenty. For active trading or hedging: every few seconds, or stream a feed. For accounting period close: a single end-of-day snapshot is correct.


Get Started With Live Currency Pair Data

Currency pairs are the language of FX. Once you have a clean mental model of major / minor / exotic and a tidy set of normalization helpers in your code, every other FX feature you build — converters, multi-currency checkout, SaaS billing, reporting — becomes dramatically easier.

Ready to plug live rates into your project? Sign up for free and get a Finexly API key in under a minute — no credit card required. You will get 1,000 requests per month free, access to all 170+ currencies, and the same mid-market rates used by professional fintech products. When you outgrow the free tier, our paid plans start at a price that fits indie projects and scale to enterprise volume.

If you want to compare options first, see our breakdown of the best currency converter API for 2026.

Vlado Grigirov

Senior Currency Markets Analyst & Financial Strategist

Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...

View full profile →

Udostępnij ten artykuł