Valutakurs.nu
Daily krona exchange rates from Riksbanken since 1993, a page for every currency and year, and a tool that checks what a bank charged on a card payment abroad.
What it is
Valutakurs.nu is written in Swedish and published only in Swedish. There is no English edition.
It publishes daily exchange rates against the Swedish krona from Sveriges riksbank, back to 1993. Nine currencies have pages of their own: EUR, USD, GBP, NOK, DKK, CHF, PLN, THB and TRY. The converter, the tool and the API cover all 29 series Riksbanken still publishes.
There is a page for every currency and every year, with monthly averages, the high and the low with the dates they fell on, the year-end rate and every daily observation of that year. Each row carries its own date as an anchor, so a link can land on a single day. The same figures download as CSV or Excel, and the open API serves them as JSON.
The launch tool, Valutapåslagskollen, answers one question: what did the bank charge on a card payment abroad? A visitor pastes a line from a statement and the tool compares the rate they paid with Riksbanken’s rate for the same day.
Getting the numbers right
The tool is careful about what it claims. It reports a deviation from Riksbanken’s reference rate and never calls it a hidden fee, because it does not know what the bank paid for the currency.
Riksbanken is the only source the pages are built from. The European Central Bank’s rates are fetched as well, but only to disagree: a gap wider than 0.5 per cent goes to a corrections queue for review.
That check has a date in it. Measured across the whole history, Riksbanken’s rates match ECB’s krona cross rates from 2023-11-27 onwards. Before that the two institutions fixed at different times of day, which on the US dollar is an average gap of 0.28 per cent and on the Swiss franc reached 14 per cent on 2015-01-15. Reconciling the older half would have queued about 7,500 differences that the clock already explains. It runs from 2023-11-27 instead, and over the 708 days since then it has found one real anomaly.
Averages are computed from daily observations, never from other averages. Rounding happens once, at display.
Which figure is shown matters as much as how it was computed. For a completed year the headline is Riksbanken’s own published average, labelled as theirs. The site’s calculated average is the headline only for the year in progress, and it says so. Every figure on the page carries one label or the other.
The arithmetic is checked against the institution that published the data. Every completed year of every currency is compared with Riksbanken’s published annual average, read from the same API rather than scraped off a table. The widest gap anywhere in the history is 0.00232 per cent.
An observation is never edited. A revision arrives as a new row, and the database refuses UPDATE and DELETE on that table outright, so the rule holds for a session at the console as well as for the worker. The public corrections page is generated from those rows.
How it is built
Astro 5 with Svelte islands, a Node worker on systemd timers, and Postgres 16 with Drizzle. No visitor request reaches Riksbanken: pages are built from the database on the server, and the converter asks the site’s own API for any other date.
The charts are rendered as SVG on the server before any JavaScript runs, so a year reads the same with scripting off.
The worker fetches twice on banking days, reconciles against ECB, recomputes the aggregates nightly, and rebuilds the site only when the data actually changed. A dataset version is created by an ingest that inserted or revised something, never by a run that found nothing new.
Two conditions stop a publish rather than ship a wrong number: fewer series than expected, and a day-on-day move above 5 per cent that ECB does not corroborate. Both send mail.
There are no ads, no accounts and no logins. The markup tool stores nothing about the visitor: not the merchant text, not the IP address, not the user agent.