Skip to content
Excel guide

Exchange rates in Excel with an API and Power Query

Load live, historical and monthly average exchange rates into Excel tables with Power Query – the API key sent as an HTTP header, refreshed on open or every hour, no VBA required.

Last updated: · fxapi team

You can load exchange rates into Excel from an API with Power Query, the data tool built into Excel for Windows (Microsoft 365 and Excel 2016 or later). This guide connects Excel to the fxapi FX rates API: latest rates, a historical date, monthly average rates as CSV, conversion formulas and a refresh schedule – with your API key sent in a request header rather than pasted into a URL.

Before you start

  • An fxapi key from the free sign-up.
  • Excel for Windows with Data → Get Data (Power Query).
EndpointGives youPlans
/v1/latestLatest rates for 190+ currenciesAll
/v1/historicalEnd-of-day rates for one dateAll
/v1/averageMonthly, quarterly or yearly averages, CSV or JSONAll
/v1/rangeDaily (or finer) time series, CSV or JSONProfessional and up

Step 1: create an API key parameter

In Excel: Data → Get Data → Launch Power Query Editor → Home → Manage Parameters → New Parameter.

  • Name: FxApiKey
  • Type: Text
  • Current value: your API key

A parameter keeps the key in one place and avoids the privacy-level (“Formula.Firewall”) errors you can get when a query reads the key from a worksheet cell.

Step 2: latest exchange rates in Excel

The quickest route is the UI: Data → Get Data → From Other Sources → From Web → Advanced. Enter https://api.fxapi.com/v1/latest?base_currency=EUR as the URL, add an HTTP request header apikey with your key, and choose Anonymous when Excel asks for credentials.

For a cleaner, reusable query, open Home → Advanced Editor and paste:

let
    Source = Json.Document(
        Web.Contents(
            "https://api.fxapi.com/v1/latest",
            [
                Query   = [base_currency = "EUR"],
                Headers = [apikey = FxApiKey]
            ]
        )
    ),
    UpdatedAt = Source[meta][last_updated_at],
    AsTable   = Record.ToTable(Source[data]),
    Expanded  = Table.ExpandRecordColumn(AsTable, "Value", {"code", "value"}, {"Code", "Rate"}),
    Typed     = Table.TransformColumnTypes(Expanded, {{"Code", type text}, {"Rate", type number}}),
    Stamped   = Table.AddColumn(Typed, "LastUpdatedAt", each UpdatedAt, type text)
in
    Stamped

Name the query Rates and choose Close & Load. You get a table with one row per currency: Rate is the number of units of that currency per 1 EUR, and LastUpdatedAt is the UTC timestamp of the data. Keeping the URL fixed and passing parameters through Query also lets the query refresh in Power BI later.

Step 3: convert amounts with XLOOKUP

With a EUR base, every rate means “units of currency X per 1 EUR”:

EUR → USD:   =[@AmountEUR] * XLOOKUP("USD", Rates[Code], Rates[Rate])
USD → EUR:   =[@AmountUSD] / XLOOKUP("USD", Rates[Code], Rates[Rate])
GBP → USD:   =[@AmountGBP] / XLOOKUP("GBP", Rates[Code], Rates[Rate]) * XLOOKUP("USD", Rates[Code], Rates[Rate])

The last line is a cross rate through the base currency, so one request covers every currency pair. The API also has a /v1/convert endpoint (Basic plan and up), but in a spreadsheet the formulas above do the same job without extra requests. Round the result with ROUND(x, 2) – or 0 for JPY and 3 for KWD; see currency rounding and precision.

Step 4: a historical exchange rate for a date

Change the endpoint and add a date (from 1999-01-01 up to yesterday):

Web.Contents(
    "https://api.fxapi.com/v1/historical",
    [
        Query   = [date = "2024-12-31", base_currency = "EUR", currencies = "USD,GBP,CHF"],
        Headers = [apikey = FxApiKey]
    ]
)

Values are end-of-day rates (UTC). Avoid invoking a historical query once per table row: each distinct date is a separate request. For a series, use monthly averages (below) or /v1/range on the Professional plan.

Step 5: monthly average rates as CSV

For month-end reporting and IAS 21 / ASC 830 translation, /v1/average returns monthly averages – plus the min and max – for a whole period in one request. With format=csv, Power Query reads it directly:

let
    Source = Csv.Document(
        Web.Contents(
            "https://api.fxapi.com/v1/average",
            [
                Query = [
                    base_currency = "EUR",
                    currencies    = "USD,GBP,CHF",
                    date_from     = "2025-10-01",
                    date_to       = "2026-09-30",
                    period        = "month",
                    format        = "csv"
                ],
                Headers = [apikey = FxApiKey]
            ]
        ),
        [Delimiter = ",", Encoding = 65001, QuoteStyle = QuoteStyle.Csv]
    ),
    Promoted = Table.PromoteHeaders(Source, [PromoteAllScalars = true]),
    Typed = Table.TransformColumnTypes(
        Promoted,
        {
            {"date_from", type date}, {"date_to", type date}, {"days", Int64.Type},
            {"average", type number}, {"min", type number}, {"max", type number}
        },
        "en-US"
    )
in
    Typed

The CSV columns are period, date_from, date_to, days, source, base_currency, currency, average, min, max. Daily rates are converted to your base currency first and then averaged; the first and last periods are clipped to your date span. Use period = "quarter" or "year" for other reporting periods. The "en-US" culture argument makes the decimal point parse correctly on any regional setting.

On the Professional plan, /v1/range with format=csv returns a daily series with columns datetime, base_currency, currency, value – handy for charts and pivot tables. See the time series API.

Step 6: set a refresh schedule

In Data → Queries & Connections, right-click the query → Properties:

  • Refresh every N minutes – match your plan’s update interval: daily data on Free, hourly on Basic, every 60 seconds on Professional and Enterprise (pricing).
  • Refresh data when opening the file – good default for reports.
  • Enable background refresh – keeps Excel responsive.

Budget your quota: one query refreshing hourly for eight working hours a day uses roughly 170 requests a month; refreshing on open only is usually a few dozen. The Free plan includes 300 requests per month.

Errors you may see

Typical symptomHTTP statusFix
Credentials prompt or “Access to the resource is forbidden”401Check the FxApiKey parameter
“Access to the resource is forbidden”403Endpoint not in your plan (/v1/range needs Professional)
“Web.Contents failed to get contents … (422)”422Check dates (≤ yesterday, ≥ 1999-01-01) and currency codes
“… (429): Too Many Requests”429Monthly quota used up, or more than 10 requests/minute on Free

To see the API’s own error text, wrap the call: Web.Contents(url, [..., ManualStatusHandling = {401, 403, 422, 429}]) and read the response body with Text.FromBinary.

Next steps

Frequently asked questions

How do I get exchange rates into Excel automatically?
Use Power Query: Data → Get Data → From Web, call https://api.fxapi.com/v1/latest with your key in the apikey header, and set the query to refresh on open or every N minutes.
Can I get monthly average exchange rates in Excel?
Yes. /v1/average with period=month&format=csv returns one row per currency and month, including min and max. It’s available on every plan, including Free, and a whole year costs one request.
Why does Excel ask for credentials when I call the API?
Power Query asks how to authenticate to every new web source. Choose Anonymous – the key travels in the apikey header defined in the query.
Does the refresh schedule work when the workbook is closed?
No. Excel refreshes Power Query only while the workbook is open. For unattended refreshes, run the same query in Power BI or a scheduled script.
Where should I store the API key in the workbook?
In a Power Query parameter. It isn’t shown on any sheet, but anyone with the file can read it in the Power Query editor, so share workbooks containing a key carefully.
Free plan · no credit card

Get your free exchange rate API key

300 requests a month, latest and historical rates, fluctuation and averages – free forever. Upgrade when you need faster updates or more requests.