Currency Exchange Rates API for Invoices: Which Rate to Use

Reviewed by Madhushan, Fintech Developer — November 2026

When you issue an invoice in a foreign currency, two questions follow. Which rate converts the amounts into your reporting or tax currency? And which date does that rate come from? A currency exchange rates API for invoices has to answer both, and the answer is usually set by tax law, not by your preference. This guide covers the tax-point rule, the official rates that laws name, what to store on the invoice, and code to fetch an official rate for a given date.

Not tax advice. This is a developer's summary of common rules. Confirm the rule for your business and country with a tax adviser or the tax authority.

The date: tax point or date of supply

Most VAT and GST systems tie the conversion to one date: the tax point, also called the time or date of supply. That is the date the tax becomes due. Depending on the country and the transaction, it can be the delivery date, the invoice date or the payment date.

So the rule for your code is simple. Do not use "today's rate" when the invoice is generated. Use the rate for the tax-point date. If you generate an invoice on 12 November for a supply on 9 November, the rate date should follow 9 November, under whatever rule applies to you.

Official rates named by law

Many tax systems name the source of the rate as well as the date. Some examples:

The pattern is the same across these: an institution, a date rule, and a table. Your system should fetch from that institution's table, not from a payment provider or a card network.

Mid-market for display, official for the tax line

An invoice system often needs two different rates, used for two different jobs.

JobRateWhy
Showing an estimated price in a quote or checkoutMid-market, currentClosest to what the market is doing right now
Converting the VAT or GST amount on the invoiceThe official rate the rule namesThe tax authority checks against that table
Booking the invoice in the ledgerThe rate your accounting policy namesOften the same official table, for consistency
Recording the payment receivedThe rate actually applied by the bankGives the realised FX gain or loss

Mixing these up is the most common mistake. A live mid-market rate is the right number to show a customer a price. It is not the rate a VAT rule names. More on the difference in mid-market vs retail exchange rates.

What to store on the invoice

Store enough to reproduce the number later without calling any API.

Several systems also require the rate to be printed on the invoice itself. UAE tax invoices are one example. Even where it is not required, printing "Rate: 4.112542 AED per EUR, Central Bank of the UAE, 9 November 2026" answers most questions before they are asked.

Fetching an official rate for a date

The AllRatesToday central bank endpoint returns an institution's official table for a date: GET /api/v1/central-bank/{bank}/{YYYY-MM-DD}. The response carries the requested date, the institution's own rate_date, and the rates.

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://allratestoday.com/api/v1/central-bank/cbuae/2026-11-08"
# "requested_date": "2026-11-08", "rate_date": "2026-11-06",
# "published_on_requested_date": false,
# "rates": [ ... { "base": "EUR", "quote": "AED", "type": "reference", "value": 4.091466 }, ... ]

8 November 2026 is a Sunday. The CBUAE does not issue rates at weekends, so the response returns Friday's table and says so. Here is the same lookup in JavaScript, with the fields you need to store:

async function officialRate(bank, date, base, quote) {
  const res = await fetch(
    `https://allratestoday.com/api/v1/central-bank/${bank}/${date}`,
    { headers: { Authorization: `Bearer ${process.env.ALLRATES_API_KEY}` } }
  );
  if (!res.ok) throw new Error(`Official rate lookup failed: ${res.status}`);
  const table = await res.json();

  const row = table.rates.find((r) => r.base === base && r.quote === quote);
  if (!row) throw new Error(`${bank} has no ${base}/${quote} on ${table.rate_date}`);

  return {
    rate: row.value,
    source: bank,
    rateDate: table.rate_date,
    taxPointDate: date,
    publishedOnDate: table.published_on_requested_date,
    fetchedAt: new Date().toISOString(),
  };
}

// EUR invoice, VAT payable in AED, supply on 8 November 2026
const fx = await officialRate("cbuae", "2026-11-08", "EUR", "AED");
const netEur = 1000.0;
const vatEur = netEur * 0.05;
const vatAed = Math.round(vatEur * fx.rate * 100) / 100; // round once, at the end
console.log(`VAT AED ${vatAed.toFixed(2)} at ${fx.rate} (${fx.source}, ${fx.rateDate})`);

A few points about this code:

Swap cbuae for the institution your rule names: ecb, hmrc and the others are listed on the central bank rates API page. The @allratestoday/central-bank package on npm and allratestoday-central-bank on PyPI wrap the same endpoint. Dated tables and history are on paid plans, and the Official plan covers any past date with JSON, CSV, XML and XLSX output for ERP imports.

A checklist for your invoicing code

  1. The rate date follows the tax-point date, not the generation date.
  2. The source is the institution your tax rule names.
  3. Weekend and holiday fallback is written down and applied the same way every time.
  4. Rate, source, rate date and lookup time are stored with the invoice.
  5. Rounding happens once, on the converted amount.
  6. Display prices may use a live mid-market rate. The tax line does not.

If you are still choosing a provider for the display side, the free currency API comparison covers update frequency and limits. For the tax side, the question is simpler: which institution does the rule name, and can you get its table for a date.

FAQ

Which exchange rate should I use on a foreign-currency invoice?

For the tax amount, use the rate your tax rule names, taken on the tax point or date of supply. Many countries name an official rate, such as the Central Bank of the UAE rate for UAE VAT or HMRC's monthly rates for UK customs. For showing a price before the sale, a mid-market rate is fine.

Can I use a mid-market rate for VAT on an invoice?

Only if your tax rule allows it. Where the law names an official rate, use that rate for the tax line. A mid-market rate is a market snapshot, not the rate a tax authority names.

What should I store with each invoice?

Store the rate, the source institution, the official rate date of the table, the date you looked it up, and the converted amounts. That lets you reproduce the figure in an audit.

What if the date of supply is a weekend or a holiday?

Most central banks do not issue rates on non-working days. The usual practice is to use the latest table before the date. Write that fallback into your policy and apply it the same way every time.

Is this tax advice?

No. It is a developer's summary of common rules. Confirm the rule that applies to your business with your tax adviser or the tax authority.

The rate the rule names, by date

Official tables from 123 central banks and 6 tax authorities, each with the institution's own rate date, as JSON, CSV, XML or Excel. Dated tables are on paid plans.

See plans

Related Articles