Tutorial/Excel quickstart
Tutorial

Live exchange rates in Excel with Power Query

Pull live FX rates into Excel with a Power Query M query against exchangerate.dev. Works on Mac and Windows, no add-in. Free tier: 10,000 calls a month, no card.

MMexchangerate.dev·Jun 29, 2026·5 min read

The cleanest way to get live exchange rates into Excel is a Power Query M query that calls /v1/latest/USD and loads the rates onto a worksheet. It refreshes on workbook open or a manual click, runs the same on Mac and Windows, and needs no add-in. A free key covers 10,000 calls a month. This is the live-data feed an FX-linked financial model wants — DCF inputs, hedging sheets, a multi-currency P&L that updates when you open it.

Key points
Power Query M is built into Excel on Mac and Windows — no add-in, and no WEBSERVICE(), which is Windows-only and breaks on Mac.
One call to /v1/latest/{base} returns every rate; split the base URL from RelativePath so scheduled refresh keeps working.
Pass your key as Authorization: Bearer exr_live_..., or X-API-Key if a connector cannot set the Authorization header.
The free tier is 10,000 calls a month at 12 requests a minute, with no card required.
Rates are indicative — built for models, analytics, and display, not for settling a trade.

Get a free API key

Sign up at exchangerate.dev/signup. After email confirmation your dashboard shows a key starting with exr_live_. Copy it — you will paste it into the query as a parameter. The free tier is 10,000 calls a month, no card required.

Open the Power Query editor

From the Excel ribbon, click Data → Get Data → Launch Power Query Editor. Inside the editor, click Home → New Source → Blank Query, then View → Advanced Editor. You will paste the M query into that box in the next step.

Paste the M query

Replace the editor contents with the query below and click Done, then rename the query FxRates in the right rail. The RelativePath argument is not optional — without it, scheduled refresh in Microsoft 365 fails with a credentials error.

Power Query · Advanced Editorcopy
// excel: Power Query M query "FxRates"
// curl-equivalent: https://api.exchangerate.dev/v1/latest/USD
// Replace ApiKey with your exchangerate.dev key from /signup
let
    ApiKey = "exr_live_replace_with_your_key_here",
    Base = "USD",
    Source = Json.Document(
        Web.Contents(
            "https://api.exchangerate.dev",
            [
                RelativePath = "v1/latest/" & Base,
                Headers = [#"Authorization" = "Bearer " & ApiKey]
            ]
        )
    ),
    Rates = Record.ToTable(Source[rates]),
    Renamed = Table.RenameColumns(Rates, {{"Name", "currency"}, {"Value", "rate"}})
in
    Renamed

Load to a worksheet, choose Anonymous

Click Home → Close & Load. Excel drops a two-column table — currency and rate — onto a new sheet. On first run Excel asks how to authenticate the https://api.exchangerate.dev source: choose Anonymous. Your key travels in the header, not the URL, so Anonymous is correct. Press Ctrl+Alt+F5 any time to refresh.

Switch the base or filter to a few pairs

Change the Base to re-base every rate, or add a symbols query to return only the pairs you need — fewer rows, same single call:

Power Query · variantscopy
// Re-base every rate to the euro
Base = "EUR"

// Return only the quote currencies you need (one call, fewer rows)
RelativePath = "v1/latest/USD",
Query = [symbols = "EUR,GBP,JPY"]

// One pair, rate calculated for you
RelativePath = "v1/convert/USD/JPY/1"   // read Source[rate]
Building this with an AI assistant?
exchangerate.dev ships an MCP server and an llms.txt, so Claude, Cursor, or ChatGPT can read the live schema and write this query for you. Ask it: "write an Excel Power Query M query that pulls USD rates from exchangerate.dev with my key in the Authorization header, using RelativePath so refresh works." See the MCP guide.

Refresh and free-tier fit

Excel does not poll on its own. The table refreshes when you open the workbook, click Refresh All, or set a periodic refresh under Data → Queries & Connections → Properties. The math stays well inside the free tier:

  • 10,000 calls a month, 12 requests a minute, no card
  • A typical model fires a handful of calls a day (open + a few manual refreshes)
  • Even a 5-minute auto-refresh during market hours lands near 100 calls a day
  • Covers /v1/latest, /v1/convert, /v1/range, and /v1/{date}/{base}
CodeSymptomFix
401DataSource.Error: 401Key missing or invalid. Re-paste it into ApiKey, then clear any stored credential under Data → Get Data → Data Source Settings for api.exchangerate.dev.
429429 Too Many RequestsYou passed the 12-per-minute cap. Stagger refreshes across queries, or move up a tier at /pricing.
Excel keeps asking for credentialsYou connected to the full URL instead of using RelativePath. Copy the split base + RelativePath query above, and choose Anonymous.
Indicative rates, not for settlement
These rates are published for models, analytics, and display. They are not a dealing quote — do not use them to settle a trade or transfer. Every response says so in its notice field.
MM
exchangerate.dev
Integration guides for developers.

Keep reading

TutorialLive exchange rates in Google SheetsRead TutorialCurrency conversion in JavaScript and Node.jsRead TutorialHow to get exchange rates in PythonRead