<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: viraj geeth</title>
    <description>The latest articles on DEV Community by viraj geeth (@viraj_geeth_e6dc448fe4d43).</description>
    <link>https://dev.to/viraj_geeth_e6dc448fe4d43</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3874173%2F195b59fe-6e41-4083-bac9-db75e702a6a6.png</url>
      <title>DEV Community: viraj geeth</title>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viraj_geeth_e6dc448fe4d43"/>
    <language>en</language>
    <item>
      <title>Loading Official Central Bank Exchange Rates into Odoo (res.currency.rate, the Right Direction)</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Fri, 16 Oct 2026 13:38:06 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/loading-official-central-bank-exchange-rates-into-odoo-rescurrencyrate-the-right-direction-1c3d</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/loading-official-central-bank-exchange-rates-into-odoo-rescurrencyrate-the-right-direction-1c3d</guid>
      <description>&lt;p&gt;Odoo's &lt;strong&gt;Automatic Currency Rates&lt;/strong&gt; setting (module &lt;code&gt;currency_rate_live&lt;/code&gt;) pulls from a fixed list of providers: the ECB, the Swiss FTA, the Bank of Canada, Banxico and a few more. If the central bank your statutory accounts must follow is on that list, use it and stop reading.&lt;/p&gt;

&lt;p&gt;If it is not, or you run subsidiaries under several central banks and want one feed, you write the rows yourself. The good news is that &lt;code&gt;res.currency.rate&lt;/code&gt; is one of the most stable models in Odoo and the loader is short. The full version with notes is in the &lt;a href="https://allratestoday.com/docs/integrations/odoo/" rel="noopener noreferrer"&gt;Odoo guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rate Odoo stores
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;res.currency.rate.rate&lt;/code&gt; is &lt;strong&gt;units of the foreign currency per 1 unit of the company currency&lt;/strong&gt;. For a EUR company and USD that is USD per EUR, which is the ECB's own direction, so nothing to invert.&lt;/p&gt;

&lt;p&gt;For an INR company following the Reserve Bank of India, which publishes INR per USD, you need the inverse. Do not divide in your own code. Ask the API for the pair in Odoo's direction and let it invert, flagging what it did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET https://allratestoday.com/api/v1/central-bank/rbi/latest?source=INR&amp;amp;target=USD

{ "bank": "rbi", "rate_date": "2026-10-09", "source": "INR", "target": "USD",
  "rate": 0.01035, "derived": true, "method": "inverse" }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;derived: true&lt;/code&gt; with &lt;code&gt;method: "inverse"&lt;/code&gt; is the line you want in your audit file. When the bank publishes the pair directly you get &lt;code&gt;derived: false, method: "published"&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The loader
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;xmlrpc.client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PWD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://erp.example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prod&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bot@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api-key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;BANK&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ecb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;ART&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer art_live_your_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;common&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmlrpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ServerProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/xmlrpc/2/common&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;uid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PWD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="n"&gt;models&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xmlrpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ServerProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/xmlrpc/2/object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute_kw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PWD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;kw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;company&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;res.company&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;read&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;currency_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;res.currency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;read&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;currency_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;res.currency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_read&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currency_id&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://allratestoday.com/api/v1/central-bank/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BANK&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/latest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                     &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ART&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;                                   &lt;span class="c1"&gt;# bank does not publish this currency
&lt;/span&gt;    &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;vals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;currency_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;currency_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rate_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;company_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;existing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;res.currency.rate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;currency_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currency_id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rate_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;company_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;res.currency.rate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;write&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;existing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;res.currency.rate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;create&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rate_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;method&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three details that bite people:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;name&lt;/code&gt; is the effective date&lt;/strong&gt;, not the run date. Always use the bank's &lt;code&gt;rate_date&lt;/code&gt;. If you run the loader on a Monday for a bank that publishes on business days, you get Friday's table dated Friday, which is correct.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-company&lt;/strong&gt;: run the loop per company with that company's home currency, and per bank code if the subsidiaries sit under different central banks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Month-end sources&lt;/strong&gt; such as HMRC's monthly table or a monthly-average publisher load the same way on a monthly cron.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Run it inside Odoo
&lt;/h2&gt;

&lt;p&gt;Put the loop in a small custom module and register an &lt;code&gt;ir.cron&lt;/code&gt; that runs daily after the bank's publication time. Inside Odoo the same logic uses &lt;code&gt;self.env['res.currency.rate']&lt;/code&gt; and &lt;code&gt;requests&lt;/code&gt;, with the API key in an &lt;code&gt;ir.config_parameter&lt;/code&gt; rather than in the code. An &lt;code&gt;inverse_company_rate&lt;/code&gt; field also exists from Odoo 14; writing either field is fine, but be consistent so reruns update rather than fight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it without a key
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;https://allratestoday.com/api/open/central-bank/ecb&lt;/code&gt; returns the latest ECB table keyless, so you can prototype the loader before signing up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Odoo guide: &lt;a href="https://allratestoday.com/docs/integrations/odoo/" rel="noopener noreferrer"&gt;https://allratestoday.com/docs/integrations/odoo/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;121 central banks covered, with each bank's publication cadence: &lt;a href="https://allratestoday.com/central-bank-rates-api/" rel="noopener noreferrer"&gt;https://allratestoday.com/central-bank-rates-api/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Other ERPs: &lt;a href="https://allratestoday.com/docs/integrations/" rel="noopener noreferrer"&gt;https://allratestoday.com/docs/integrations/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Free API key: &lt;a href="https://allratestoday.com/register/" rel="noopener noreferrer"&gt;https://allratestoday.com/register/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rates are redistributed from each institution's public publication. They are reference rates for accounting, tax and compliance, not dealing quotes.&lt;/p&gt;

</description>
      <category>odoo</category>
      <category>python</category>
      <category>erp</category>
      <category>api</category>
    </item>
    <item>
      <title>Official Central Bank Exchange Rates in Dynamics 365 Business Central (No Extension Needed)</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Tue, 13 Oct 2026 16:35:35 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/official-central-bank-exchange-rates-in-dynamics-365-business-central-no-extension-needed-3jkp</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/official-central-bank-exchange-rates-in-dynamics-365-business-central-no-extension-needed-3jkp</guid>
      <description>&lt;p&gt;If your finance team has to book foreign-currency transactions at the rate a specific central bank publishes, Business Central can do it without a single line of AL. The product has shipped a URL-driven importer since NAV 2015, the &lt;strong&gt;Currency Exchange Rate Service&lt;/strong&gt;, and all it needs is an XML feed it can parse and a field mapping.&lt;/p&gt;

&lt;p&gt;This post walks through pointing that importer at an official central-bank table. The full procedure with every field is in the &lt;a href="https://allratestoday.com/docs/integrations/business-central/" rel="noopener noreferrer"&gt;Business Central guide&lt;/a&gt; on AllRatesToday.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two limits of the built-in importer
&lt;/h2&gt;

&lt;p&gt;The Currency Exchange Rate Service has two constraints that rule out most rate APIs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It reads &lt;strong&gt;XML&lt;/strong&gt;, not JSON.&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;cannot send request headers&lt;/strong&gt;, so an API key has to travel on the URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both are covered by two query parameters on the AllRatesToday central-bank endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://allratestoday.com/api/v1/central-bank/ecb/latest?format=xml&amp;amp;api_key=art_live_your_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap &lt;code&gt;ecb&lt;/code&gt; for any of the 121 bank codes on the &lt;a href="https://allratestoday.com/central-bank-rates-api/" rel="noopener noreferrer"&gt;coverage map&lt;/a&gt;: &lt;code&gt;rbi&lt;/code&gt; for the Reserve Bank of India, &lt;code&gt;boe&lt;/code&gt; for the Bank of England, &lt;code&gt;cbuae&lt;/code&gt; for the UAE, &lt;code&gt;bsp&lt;/code&gt; for the Philippines, and so on.&lt;/p&gt;

&lt;p&gt;The response is the bank's complete latest table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;response&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;bank&amp;gt;&lt;/span&gt;ecb&lt;span class="nt"&gt;&amp;lt;/bank&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;European Central Bank&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;rate_date&amp;gt;&lt;/span&gt;2026-10-09&lt;span class="nt"&gt;&amp;lt;/rate_date&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;rates&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;rate&amp;gt;&amp;lt;base&amp;gt;&lt;/span&gt;EUR&lt;span class="nt"&gt;&amp;lt;/base&amp;gt;&amp;lt;quote&amp;gt;&lt;/span&gt;USD&lt;span class="nt"&gt;&amp;lt;/quote&amp;gt;&amp;lt;type&amp;gt;&lt;/span&gt;reference&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&amp;lt;value&amp;gt;&lt;/span&gt;1.1206&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&amp;lt;/rate&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;rate&amp;gt;&amp;lt;base&amp;gt;&lt;/span&gt;EUR&lt;span class="nt"&gt;&amp;lt;/base&amp;gt;&amp;lt;quote&amp;gt;&lt;/span&gt;GBP&lt;span class="nt"&gt;&amp;lt;/quote&amp;gt;&amp;lt;type&amp;gt;&lt;/span&gt;reference&lt;span class="nt"&gt;&amp;lt;/type&amp;gt;&amp;lt;value&amp;gt;&lt;/span&gt;0.84763&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&amp;lt;/rate&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="nt"&gt;&amp;lt;/rates&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/response&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want to try before you sign up? The keyless copy at &lt;code&gt;https://allratestoday.com/api/open/central-bank/ecb&lt;/code&gt; returns the same table as JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the service
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Search for &lt;strong&gt;Currency Exchange Rate Services&lt;/strong&gt;, choose &lt;strong&gt;New&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Code it &lt;code&gt;ECB-OFFICIAL&lt;/code&gt;, paste the URL into &lt;strong&gt;Service URL&lt;/strong&gt;, click &lt;strong&gt;Preview&lt;/strong&gt;. Business Central fetches the feed and shows the XML tree.&lt;/li&gt;
&lt;li&gt;On &lt;strong&gt;Field Mapping&lt;/strong&gt;, set the &lt;strong&gt;Parent Node&lt;/strong&gt; to the repeating &lt;code&gt;rate&lt;/code&gt; element and map the fields below.&lt;/li&gt;
&lt;li&gt;Enable the service and give the &lt;strong&gt;Job Queue&lt;/strong&gt; entry a run time after the bank's publication time. The ECB publishes around 16:00 CET; every bank's cadence is on its page.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The field mapping, and why direction matters
&lt;/h2&gt;

&lt;p&gt;Business Central stores each rate as &lt;em&gt;Exchange Rate Amount&lt;/em&gt; (foreign) against &lt;em&gt;Relational Exch. Rate Amount&lt;/em&gt; (local). Which of the feed's two sides goes where depends on how the bank quotes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Business Central field&lt;/th&gt;
&lt;th&gt;Bank quotes foreign per 1 home (ECB, BoE, RBA)&lt;/th&gt;
&lt;th&gt;Bank quotes home per 1 foreign (RBI, CBN, BSP)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Currency Code&lt;/td&gt;
&lt;td&gt;&lt;code&gt;quote&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;base&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Starting Date&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rate_date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rate_date&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exchange Rate Amount&lt;/td&gt;
&lt;td&gt;&lt;code&gt;value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relational Exch. Rate Amount&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;value&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The ECB says "1 EUR = 1.1206 USD", so USD is the quote and the value is the foreign amount. The RBI says "1 USD = 96.6149 INR", so USD is the base and the value is the local amount. Map it once per bank and the importer handles every currency in the table the same way.&lt;/p&gt;

&lt;p&gt;If you would rather not think about direction at all, the endpoint can resolve a single pair for you: &lt;code&gt;?source=USD&amp;amp;target=EUR&lt;/code&gt; returns one rate in exactly that direction, with &lt;code&gt;derived&lt;/code&gt; and &lt;code&gt;method&lt;/code&gt; fields that say whether it was published as-is, inverted, or crossed through the home currency. That is the audit trail an external auditor asks for.&lt;/p&gt;

&lt;h2&gt;
  
  
  When you do want an extension
&lt;/h2&gt;

&lt;p&gt;The built-in service imports a whole table on a schedule. If you need per-company bank codes, a "run now" action, or a log of currencies skipped because they are not set up in the Currency table, an AL codeunit using &lt;code&gt;HttpClient&lt;/code&gt; against the JSON endpoint is about 150 lines. The &lt;code&gt;rate_date&lt;/code&gt;, &lt;code&gt;stale&lt;/code&gt; and &lt;code&gt;age_days&lt;/code&gt; fields in the JSON tell the codeunit whether the bank has published a new table yet, so you never post a stale rate as today's.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Guide with every screenshot-free step: &lt;a href="https://allratestoday.com/docs/integrations/business-central/" rel="noopener noreferrer"&gt;https://allratestoday.com/docs/integrations/business-central/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;121 central banks and 3 tax authorities covered: &lt;a href="https://allratestoday.com/central-bank-rates-api/" rel="noopener noreferrer"&gt;https://allratestoday.com/central-bank-rates-api/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Other ERPs (SAP, Odoo, Xero, QuickBooks): &lt;a href="https://allratestoday.com/docs/integrations/" rel="noopener noreferrer"&gt;https://allratestoday.com/docs/integrations/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Free API key: &lt;a href="https://allratestoday.com/register/" rel="noopener noreferrer"&gt;https://allratestoday.com/register/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rates are redistributed from each institution's public publication. They are reference rates for accounting, tax and compliance, not dealing quotes.&lt;/p&gt;

</description>
      <category>dynamics365</category>
      <category>erp</category>
      <category>api</category>
      <category>fintech</category>
    </item>
    <item>
      <title>@allratestoday/sdk: The Official JavaScript SDK for Real-Time Exchange Rates</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Sun, 27 Sep 2026 13:38:34 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/allratestodaysdk-the-official-javascript-sdk-for-real-time-exchange-rates-29bk</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/allratestodaysdk-the-official-javascript-sdk-for-real-time-exchange-rates-29bk</guid>
      <description>&lt;p&gt;Wiring a currency API into a Node or browser app shouldn't take more than a few minutes. With the &lt;a href="https://www.npmjs.com/package/@allratestoday/sdk" rel="noopener noreferrer"&gt;&lt;code&gt;@allratestoday/sdk&lt;/code&gt;&lt;/a&gt; package, it doesn't.&lt;/p&gt;

&lt;p&gt;It's the official JavaScript SDK for the &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;AllRatesToday API&lt;/a&gt; — a real-time FX service serving mid-market rates for 160+ currencies — and it covers everything the raw API does, with TypeScript types, zero runtime dependencies, and an ergonomic surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this SDK
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⚡ &lt;strong&gt;Zero runtime dependencies&lt;/strong&gt; — pure TypeScript, uses native &lt;code&gt;fetch&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;📡 &lt;strong&gt;Real-time data&lt;/strong&gt; — rates refreshed every 60 seconds&lt;/li&gt;
&lt;li&gt;💹 &lt;strong&gt;Mid-market rates&lt;/strong&gt; — no retail spread baked in&lt;/li&gt;
&lt;li&gt;🌍 &lt;strong&gt;160+ currencies&lt;/strong&gt; — major, minor, and exotic pairs (plus precious metals)&lt;/li&gt;
&lt;li&gt;🔷 &lt;strong&gt;Type-safe&lt;/strong&gt; — full TypeScript, intelligent autocomplete, strongly typed responses&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;Universal&lt;/strong&gt; — works in Node.js 18+ and modern browsers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @allratestoday/sdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Grab a free API key at &lt;a href="https://allratestoday.com/register" rel="noopener noreferrer"&gt;allratestoday.com/register&lt;/a&gt; — no credit card required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AllRatesToday&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@allratestoday/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AllRatesToday&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rates&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GBP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JPY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rates&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// { EUR: 0.92, GBP: 0.78, JPY: 149.5 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Latest rates
&lt;/h2&gt;

&lt;p&gt;Get all rates against a base, or filter to the pairs you actually need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// All rates from USD&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;all&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Just the ones you care about — cheaper payload, same response shape&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CHF&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GBP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JPY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Historical rates
&lt;/h2&gt;

&lt;p&gt;Look up rates for a specific date — ideal for reporting, invoice re-calculation, or compliance workflows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;historical&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;historical&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2025-12-31&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GBP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Currency conversion
&lt;/h2&gt;

&lt;p&gt;Skip the math and ask for an amount:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;converted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;converted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// { from: "USD", to: "EUR", amount: 100, converted: 92.34, rate: 0.9234 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Time-series data
&lt;/h2&gt;

&lt;p&gt;For charts and trend analysis, request a range:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;series&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeseries&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;startDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2026-01-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;endDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2026-04-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chart that straight into Recharts / Chart.js / your tool of choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preset period lookups
&lt;/h2&gt;

&lt;p&gt;Sometimes you want "last 7 days" without calculating dates yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lastWeek&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;historicalByPeriod&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;period&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;7d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// '1d' | '7d' | '30d' | '1y'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Node or browser — it doesn't care
&lt;/h2&gt;

&lt;p&gt;The SDK uses native &lt;code&gt;fetch&lt;/code&gt;, so it runs the same in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js 18+&lt;/li&gt;
&lt;li&gt;Modern browsers&lt;/li&gt;
&lt;li&gt;Cloudflare Workers, Vercel Edge, Deno, Bun&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No polyfills, no adapter packages, no version-specific builds.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to pick @allratestoday/sdk vs the smaller packages
&lt;/h2&gt;

&lt;p&gt;The AllRatesToday ecosystem has a few Node packages, each with a different scope:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/@allratestoday/sdk" rel="noopener noreferrer"&gt;&lt;code&gt;@allratestoday/sdk&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Full API surface — latest, historical, time-series, conversion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/fx-rates" rel="noopener noreferrer"&gt;&lt;code&gt;fx-rates&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Minimal &lt;code&gt;rate()&lt;/code&gt; / &lt;code&gt;convert()&lt;/code&gt; + a CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/moneyify" rel="noopener noreferrer"&gt;&lt;code&gt;moneyify&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;cashify-compatible conversion with optional auto-fetch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/live-currency-rates" rel="noopener noreferrer"&gt;&lt;code&gt;live-currency-rates&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Multi-provider wrapper (Frankfurter, fawaz, AllRatesToday)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you need the full API (especially historical and time-series), use &lt;code&gt;@allratestoday/sdk&lt;/code&gt;. If you just want to convert two currencies, start with &lt;code&gt;fx-rates&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/@allratestoday/sdk" rel="noopener noreferrer"&gt;&lt;code&gt;@allratestoday/sdk&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Free API key: &lt;a href="https://allratestoday.com/register" rel="noopener noreferrer"&gt;allratestoday.com/register&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Full API reference: &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;allratestoday.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy converting.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by the team behind &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt; — an exchange rate API with real-time mid-market rates for 150+ currencies and the official published rates of 116 central banks and tax authorities, with keyless open endpoints for the central-bank data. Browse the &lt;a href="https://allratestoday.com/docs" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; or &lt;a href="https://allratestoday.com/register/" rel="noopener noreferrer"&gt;grab a free key&lt;/a&gt; to start building.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Open source: official SDKs for &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;JavaScript, Python, PHP, Go and Rust&lt;/a&gt;,&lt;br&gt;
plus an MCP server (&lt;code&gt;@allratestoday/mcp-server&lt;/code&gt;) for AI agents.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow along: &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>api</category>
      <category>fintech</category>
    </item>
    <item>
      <title>Free currency API in 2026: what the free tiers actually give you</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Sun, 27 Sep 2026 13:38:06 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/free-currency-api-in-2026-what-the-free-tiers-actually-give-you-5fm2</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/free-currency-api-in-2026-what-the-free-tiers-actually-give-you-5fm2</guid>
      <description>&lt;p&gt;Most "free currency API" searches end the same way. You pick the first provider with a free plan, ship the integration, and a month later the app breaks because you hit a 100-request cap, or the rates turn out to be yesterday's ECB fixing, or the "free" plan needed a card and it just charged you.&lt;/p&gt;

&lt;p&gt;I maintain one of these APIs (AllRatesToday), so treat the ranking with that in mind. But the comparison table below is the thing I wish I had found first, and the numbers in it are the ones on each provider's pricing page at the time of writing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four questions that matter
&lt;/h2&gt;

&lt;p&gt;Before the table, the questions a free tier has to answer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;How many requests, and per what?&lt;/strong&gt; Per month, per day, or lifetime. Lifetime caps are fine for a prototype and a trap for anything scheduled.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How fresh is the data?&lt;/strong&gt; Many free tiers serve one daily fixing, usually the ECB's 16:00 CET table of about 30 currencies. That is fine for an invoice and useless for a price display.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is there a credit-card wall?&lt;/strong&gt; Some providers put a card on the free plan so the upgrade is one click. Read the fine print about what happens at the cap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where do the rates come from?&lt;/strong&gt; Mid-market rates, a central bank's reference table, or a retail rate with a spread baked in. These differ by up to a few percent and you need to know which one you are showing.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Comparison table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;API&lt;/th&gt;
&lt;th&gt;Free tier&lt;/th&gt;
&lt;th&gt;Currencies&lt;/th&gt;
&lt;th&gt;Update frequency on free&lt;/th&gt;
&lt;th&gt;Card required&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AllRatesToday&lt;/td&gt;
&lt;td&gt;Free key, no card. Keyless open endpoint for official central-bank tables&lt;/td&gt;
&lt;td&gt;160+&lt;/td&gt;
&lt;td&gt;Real-time (60 s) with key&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CurrencyFreaks&lt;/td&gt;
&lt;td&gt;1,000 req/month&lt;/td&gt;
&lt;td&gt;1,000+ incl. crypto&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ExchangeRate-API&lt;/td&gt;
&lt;td&gt;1,500 req/month&lt;/td&gt;
&lt;td&gt;161&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;For upgrades&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Exchange Rates&lt;/td&gt;
&lt;td&gt;1,000 req/month&lt;/td&gt;
&lt;td&gt;200+&lt;/td&gt;
&lt;td&gt;Hourly&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CurrencyLayer&lt;/td&gt;
&lt;td&gt;100 req/month&lt;/td&gt;
&lt;td&gt;168&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fixer&lt;/td&gt;
&lt;td&gt;100 req/month&lt;/td&gt;
&lt;td&gt;170+&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CurrencyAPI&lt;/td&gt;
&lt;td&gt;300 req/month&lt;/td&gt;
&lt;td&gt;170+&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XE&lt;/td&gt;
&lt;td&gt;Trial only&lt;/td&gt;
&lt;td&gt;170+&lt;/td&gt;
&lt;td&gt;Up to 60 s&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alpha Vantage&lt;/td&gt;
&lt;td&gt;25 req/day&lt;/td&gt;
&lt;td&gt;Multi-asset&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ExchangeRate.host&lt;/td&gt;
&lt;td&gt;Free plan&lt;/td&gt;
&lt;td&gt;168+&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frankfurter&lt;/td&gt;
&lt;td&gt;Unlimited, keyless&lt;/td&gt;
&lt;td&gt;~30 (ECB)&lt;/td&gt;
&lt;td&gt;Daily (ECB)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fawazahmed0/currency-api&lt;/td&gt;
&lt;td&gt;Unlimited, static JSON on a CDN&lt;/td&gt;
&lt;td&gt;340&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two of those rows are not companies at all. Frankfurter is an open-source wrapper around the ECB table, and fawazahmed0's currency-api is a GitHub repo that republishes daily JSON files through jsDelivr. If daily ECB-style data is enough for you, start with one of those and skip the signup entirely. I benchmarked both every hour for a week alongside the commercial open endpoints; the static CDN file was the fastest thing in the test.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a daily fixing is enough, and when it is not
&lt;/h2&gt;

&lt;p&gt;Daily is enough for accounting, invoicing, customs and tax work. In fact for those you usually want a &lt;em&gt;specific&lt;/em&gt; daily table, the one your tax authority or central bank publishes, not a market rate. That is a different product category, and it is why I keep the official tables on a separate keyless endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ECB reference rate, no key, attribution required&lt;/span&gt;
curl &lt;span class="s2"&gt;"https://allratestoday.com/api/open/central-bank/ecb?source=EUR&amp;amp;target=USD"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bank"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecb"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rate_date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-25"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1403&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rate_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reference"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cadence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"daily"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attribution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Official rates published by ECB, served by AllRatesToday"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"terms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Free to use with visible attribution linking to allratestoday.com"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same endpoint pattern works for the other central banks in the set: swap &lt;code&gt;ecb&lt;/code&gt; for &lt;code&gt;cbuae&lt;/code&gt;, &lt;code&gt;boe&lt;/code&gt;, &lt;code&gt;rbi&lt;/code&gt;, &lt;code&gt;sbv&lt;/code&gt; and so on. &lt;code&gt;GET /api/open/central-banks&lt;/code&gt; lists them.&lt;/p&gt;

&lt;p&gt;Daily is &lt;strong&gt;not&lt;/strong&gt; enough for a checkout, a pricing page in the visitor's currency, a trading dashboard or anything where the user compares your number with Google's. For that you want mid-market rates refreshed at least every minute, and every provider in the table charges for that except the ones that grant it on the free key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-time on the free tier
&lt;/h2&gt;

&lt;p&gt;With AllRatesToday the free key gets the same 60-second mid-market feed as the paid plans. Be aware that the free allowance is a fixed block of requests, not a monthly reset: it is there to build and test against real data, and a production price display that polls on a schedule belongs on a paid plan. Either way, one fetch per minute per base currency, cached server-side, is all a price display needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://allratestoday.com/api/v1/rates?source=USD&amp;amp;target=EUR"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Node 18+ / browser&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://allratestoday.com/api/v1/rates?source=USD&amp;amp;target=EUR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ALLRATES_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 0.8778&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Historical dates, time series and CSV/XLSX output are on the same endpoints with &lt;code&gt;date=&lt;/code&gt; and &lt;code&gt;format=&lt;/code&gt; parameters. There are official SDKs for JavaScript, Python, PHP, Go and Rust if you prefer typed clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to pick
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prototype or side project:&lt;/strong&gt; a keyless source. Frankfurter, the currency-api CDN files, or the open central-bank endpoint above. No account, nothing to expire.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Price display, checkout, SaaS billing:&lt;/strong&gt; a real-time mid-market feed with a free key and no card. Cache for 60 seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accounting, tax, customs:&lt;/strong&gt; the official table from the institution your rule names, not a market rate. Use the central-bank endpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crypto plus fiat:&lt;/strong&gt; CurrencyFreaks or CurrencyAPI cover the most symbols.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stocks and forex together:&lt;/strong&gt; Alpha Vantage, with a very low free cap.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  One thing every free tier has in common
&lt;/h2&gt;

&lt;p&gt;None of them are meant to be called on every page view. Whatever you pick, put the rate behind a cache with a short TTL and fall back to the last good value when a fetch fails. That single habit turns a 100-request free plan into something you can actually ship on, and it is the difference between a demo and a product.&lt;/p&gt;

&lt;p&gt;The full ranking with per-provider notes and an FAQ lives here: &lt;a href="https://allratestoday.com/blog/best-free-currency-exchange-api-2026/" rel="noopener noreferrer"&gt;The best free currency exchange API in 2026&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>fintech</category>
    </item>
    <item>
      <title>I benchmarked 6 free exchange rate APIs every hour for a week. Here are the numbers.</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Fri, 25 Sep 2026 12:34:21 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/i-benchmarked-6-free-exchange-rate-apis-every-hour-for-a-week-here-are-the-numbers-32od</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/i-benchmarked-6-free-exchange-rate-apis-every-hour-for-a-week-here-are-the-numbers-32od</guid>
      <description>&lt;p&gt;Every "best exchange rate API" list I have read ranks providers by their pricing page. Nobody measures them. So I set up a GitHub Action that hits six free, keyless exchange rate endpoints every hour, records latency, HTTP status and the publication date in the body, and publishes the results as JSON and CSV.&lt;/p&gt;

&lt;p&gt;Disclosure up front: I build &lt;a href="https://allratestoday.com/exchange-rate-api/" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt;, which is one of the six. The harness is public, the raw data is public, and the numbers below are copied from it without editing. If you think the method is unfair to anyone, the workflow file is the place to argue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vantage:&lt;/strong&gt; GitHub Actions hosted runner, &lt;code&gt;ubuntu-latest&lt;/code&gt;, US East.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cadence:&lt;/strong&gt; hourly, since 2026-09-19. The table below covers the first 7 days (31 runs at the time of writing).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per run:&lt;/strong&gt; 3 sequential GETs per provider with a cache-busting query string and a 15 s timeout. The median of the three is recorded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uptime:&lt;/strong&gt; share of runs that returned HTTP 2xx with a parseable body.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freshness:&lt;/strong&gt; the publication date inside the response compared with the run date (UTC).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source: &lt;a href="https://github.com/AllRates-Today/central-bank-exchange-rates/blob/main/scripts/benchmark.mjs" rel="noopener noreferrer"&gt;benchmark.mjs&lt;/a&gt; and &lt;a href="https://github.com/AllRates-Today/central-bank-exchange-rates/blob/main/.github/workflows/benchmark.yml" rel="noopener noreferrer"&gt;benchmark.yml&lt;/a&gt;. Output: &lt;a href="https://github.com/AllRates-Today/central-bank-exchange-rates/blob/main/benchmark/latest.json" rel="noopener noreferrer"&gt;latest.json&lt;/a&gt; and &lt;a href="https://github.com/AllRates-Today/central-bank-exchange-rates/blob/main/benchmark/history.csv" rel="noopener noreferrer"&gt;history.csv&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results, first 7 days
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Median&lt;/th&gt;
&lt;th&gt;p90&lt;/th&gt;
&lt;th&gt;Uptime&lt;/th&gt;
&lt;th&gt;Currencies&lt;/th&gt;
&lt;th&gt;Data age&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;fawazahmed0/currency-api (jsDelivr)&lt;/td&gt;
&lt;td&gt;market, static file&lt;/td&gt;
&lt;td&gt;11 ms&lt;/td&gt;
&lt;td&gt;23 ms&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;340&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AllRatesToday open central-bank endpoint&lt;/td&gt;
&lt;td&gt;official (ECB table)&lt;/td&gt;
&lt;td&gt;31 ms&lt;/td&gt;
&lt;td&gt;68 ms&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ExchangeRate-API open endpoint&lt;/td&gt;
&lt;td&gt;market&lt;/td&gt;
&lt;td&gt;112 ms&lt;/td&gt;
&lt;td&gt;131 ms&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;166&lt;/td&gt;
&lt;td&gt;0 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FloatRates&lt;/td&gt;
&lt;td&gt;market&lt;/td&gt;
&lt;td&gt;316 ms&lt;/td&gt;
&lt;td&gt;379 ms&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;146&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frankfurter&lt;/td&gt;
&lt;td&gt;official (ECB)&lt;/td&gt;
&lt;td&gt;373 ms&lt;/td&gt;
&lt;td&gt;580 ms&lt;/td&gt;
&lt;td&gt;96.8%&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECB eurofxref-daily.xml&lt;/td&gt;
&lt;td&gt;official, primary source&lt;/td&gt;
&lt;td&gt;401 ms&lt;/td&gt;
&lt;td&gt;558 ms&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;29&lt;/td&gt;
&lt;td&gt;1 day&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;"Data age" is the gap between the publication date in the response and the run date. A 1-day age on an ECB-derived feed is normal: the ECB publishes around 16:00 CET and the date rolls the next day.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the numbers actually say
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Static beats dynamic.&lt;/strong&gt; The fastest endpoint is not an API at all. fawazahmed0's project publishes JSON files to a CDN once a day. If daily market rates are enough and you can live without an SLA, a CDN file will always win on latency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edge-cached official tables are the next tier.&lt;/strong&gt; The AllRatesToday open endpoint serves the ECB table from Cloudflare's edge, which is why it lands at 31 ms from a US runner. It carries the ECB's own publication date, so it is usable for invoices and month-end where the auditor asks which rate you used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The classic "free API" options are 100 to 400 ms.&lt;/strong&gt; ExchangeRate-API's open endpoint was the most consistent of the dynamic services: 100% uptime and a tight p90. FloatRates and Frankfurter are fine but slower, and Frankfurter dropped one run in the week. One failed run in 31 is not a verdict on Frankfurter, and the 30-day column on the live page will be fairer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Going straight to the ECB is the slowest option.&lt;/strong&gt; The primary source XML is 400 ms and still one day old. There is no freshness advantage to fetching it yourself. Cache it or use a mirror.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one should you use
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Side project, daily rates, no budget:&lt;/strong&gt; fawazahmed0's CDN files or ExchangeRate-API's open endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anything an accountant will read:&lt;/strong&gt; an official-rate endpoint that returns the publisher and date. AllRatesToday's open endpoint does that for the ECB with no key, and the keyed API covers 116 central banks plus HMRC, US Treasury and Swiss customs tables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time market rates in a checkout:&lt;/strong&gt; none of the free endpoints above. Every one is daily. You need a paid tier from any provider that quotes sub-minute updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try the two fastest yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# static CDN file, daily&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/eur.min.json | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 200

&lt;span class="c"&gt;# official ECB table with publication date, no key&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://allratestoday.com/api/open/central-bank/ecb?source=USD&amp;amp;target=EUR"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The live page at &lt;a href="https://allratestoday.com/benchmarks/exchange-rate-api/" rel="noopener noreferrer"&gt;allratestoday.com/benchmarks/exchange-rate-api&lt;/a&gt; updates hourly and adds a rolling 30-day column once there is enough history. If you want another free endpoint added to the harness, open an issue on the data repo and include a keyless URL.&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>fintech</category>
    </item>
    <item>
      <title>A currency API with no API key: AllRatesToday is now in the public-apis directory</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Tue, 22 Sep 2026 18:06:45 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/a-currency-api-with-no-api-key-allratestoday-is-now-in-the-public-apis-directory-4n5a</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/a-currency-api-with-no-api-key-allratestoday-is-now-in-the-public-apis-directory-4n5a</guid>
      <description>&lt;p&gt;&lt;a href="https://allratestoday.com/" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt; is now listed in the&lt;br&gt;
&lt;a href="https://publicapis.dev/resource/allratestoday/obgx1siv" rel="noopener noreferrer"&gt;public-apis&lt;/a&gt; directory under Currency&lt;br&gt;
Exchange. Rather than write a post that just says that, here is the part of the API that earns a&lt;br&gt;
place in a list of public APIs: a set of endpoints that need no key at all.&lt;/p&gt;
&lt;h2&gt;
  
  
  The keyless part
&lt;/h2&gt;

&lt;p&gt;Central banks and tax authorities publish an official exchange rate table, usually once per business&lt;br&gt;
day. That number is not a market rate — it is the figure a VAT return, a customs declaration or a set&lt;br&gt;
of statutory accounts has to use, because the regulation names the institution that published it.&lt;/p&gt;

&lt;p&gt;We collect those tables from 116 central banks and 3 tax authorities and serve the latest one for any&lt;br&gt;
source with no key, no signup and CORS wide open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://allratestoday.com/api/open/central-bank/ecb"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bank"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecb"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rate_date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-22"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"age_days"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stale"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cadence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"daily"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rates"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"quote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reference"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.1463&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"quote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GBP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reference"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.8578&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask for a single pair and you get the pair, plus whether it was published directly or derived:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://allratestoday.com/api/open/central-bank/cbuae?source=AED&amp;amp;target=USD"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap &lt;code&gt;ecb&lt;/code&gt; for &lt;code&gt;fed&lt;/code&gt;, &lt;code&gt;boe&lt;/code&gt;, &lt;code&gt;rbi&lt;/code&gt;, &lt;code&gt;pboc&lt;/code&gt;, &lt;code&gt;snb&lt;/code&gt;, &lt;code&gt;hmrc&lt;/code&gt;, &lt;code&gt;ustreasury&lt;/code&gt;, &lt;code&gt;bazg&lt;/code&gt; or any of the other&lt;br&gt;
codes. The catalogue is keyless too, and tells you how fresh each source is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://allratestoday.com/api/open/central-banks"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every response carries the publication date, the age in days and a &lt;code&gt;stale&lt;/code&gt; flag, which matters more&lt;br&gt;
than it sounds: a table that is one day old on a Saturday is correct behaviour, and a table that is&lt;br&gt;
nine days old is a problem. You should be able to tell those apart without guessing.&lt;/p&gt;

&lt;p&gt;The condition is attribution — a visible credit linking back — which is the same deal the data&lt;br&gt;
repository carries under CC BY 4.0.&lt;/p&gt;
&lt;h2&gt;
  
  
  In JavaScript, with no setup
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://allratestoday.com/api/open/central-bank/ecb?source=EUR&amp;amp;target=USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rate_date&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ECB reference rate on &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rate_date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: 1 EUR = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; USD`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;CORS is open, so this works from the browser. No proxy, no key in your bundle.&lt;/p&gt;
&lt;h2&gt;
  
  
  What does need a key
&lt;/h2&gt;

&lt;p&gt;The free key takes a minute and no card, and unlocks the parts that are a database query rather than&lt;br&gt;
one cached object:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time mid-market rates&lt;/strong&gt; for 160+ currencies, refreshed every 60 seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A rate on any past date&lt;/strong&gt;, with the publishing institution's own weekend and holiday rule applied
and stated in the response&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full history and time series&lt;/strong&gt;, and CSV, XML or XLSX instead of JSON&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross rates&lt;/strong&gt; computed between two currencies neither of which is the bank's home currency&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Same data, no API at all
&lt;/h2&gt;

&lt;p&gt;If you would rather not call an API, the whole central-bank archive is a git repository, mirrored to&lt;br&gt;
jsDelivr, Hugging Face and Kaggle and refreshed daily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://cdn.jsdelivr.net/gh/AllRates-Today/central-bank-exchange-rates@main/data/ecb/latest.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also an MCP server, so an AI agent can look up a rate and cite the institution and date&lt;br&gt;
instead of inventing one from training data.&lt;/p&gt;

&lt;h2&gt;
  
  
  One correction to the listing
&lt;/h2&gt;

&lt;p&gt;The directory's generated description says our rates come from Reuters and Refinitiv. They do not,&lt;br&gt;
and we do not license either. The real-time feed is aggregated institutional interbank market data;&lt;br&gt;
the official tables come from each institution's own publication. We had a sentence on our blog that&lt;br&gt;
placed the word "Reuters" next to our own sourcing, which is almost certainly what a crawler merged.&lt;br&gt;
That sentence is now fixed, and I have asked the directory to update the entry. If you are picking a&lt;br&gt;
data provider, "sourced from Reuters" is a claim worth making a vendor prove.&lt;/p&gt;




&lt;p&gt;Docs: &lt;a href="https://allratestoday.com/docs/" rel="noopener noreferrer"&gt;allratestoday.com/docs&lt;/a&gt; ·&lt;br&gt;
&lt;a href="https://allratestoday.com/openapi.json" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt; ·&lt;br&gt;
&lt;a href="https://allratestoday.com/llms.txt" rel="noopener noreferrer"&gt;llms.txt&lt;/a&gt; for agents ·&lt;br&gt;
&lt;a href="https://allratestoday.com/register/" rel="noopener noreferrer"&gt;free key&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>currency</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Auto-localize prices in React with react-currency-localizer-realtime</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Sat, 19 Sep 2026 19:50:47 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/auto-localize-prices-in-react-with-react-currency-localizer-realtime-mg2</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/auto-localize-prices-in-react-with-react-currency-localizer-realtime-mg2</guid>
      <description>&lt;p&gt;If you sell to international customers, showing prices in the visitor's local currency isn't a nice-to-have — it's a conversion-rate lever. But wiring it up usually turns into a small project: IP geolocation, exchange-rate fetching, caching, fallbacks, race conditions when the rate call is slower than render.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/react-currency-localizer-realtime" rel="noopener noreferrer"&gt;&lt;code&gt;react-currency-localizer-realtime&lt;/code&gt;&lt;/a&gt; compresses all of that into a React hook and a component. Drop it in, pass a price, done.&lt;/p&gt;

&lt;p&gt;Under the hood it uses real-time mid-market rates from the &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;AllRatesToday API&lt;/a&gt; — 160+ currencies, updated every 60 seconds, sourced from institutional interbank market data.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;⚡ &lt;strong&gt;Real-time mid-market rates&lt;/strong&gt; — no retail markup, no hidden spread&lt;/li&gt;
&lt;li&gt;🌍 &lt;strong&gt;Auto-detect&lt;/strong&gt; the user's currency via IP geolocation (no API key needed for geolocation)&lt;/li&gt;
&lt;li&gt;💱 &lt;strong&gt;160+ currencies&lt;/strong&gt; — major, minor, exotic, and precious metals&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Smart caching&lt;/strong&gt; — 24h localStorage for geolocation, 1h memory cache for rates&lt;/li&gt;
&lt;li&gt;🔀 &lt;strong&gt;Three usage patterns&lt;/strong&gt; — hook, component, or batch&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Manual override&lt;/strong&gt; — skip geolocation with an explicit currency&lt;/li&gt;
&lt;li&gt;🔷 &lt;strong&gt;TypeScript-first&lt;/strong&gt; — full type definitions&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;Zero runtime deps&lt;/strong&gt; besides React itself&lt;/li&gt;
&lt;li&gt;🪶 &lt;strong&gt;~4KB gzipped&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🛡️ &lt;strong&gt;Graceful fallbacks&lt;/strong&gt; — shows the original price if anything fails&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react-currency-localizer-realtime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React 17+ is the only peer dependency.&lt;/p&gt;

&lt;p&gt;Get a free API key at &lt;a href="https://allratestoday.com/register" rel="noopener noreferrer"&gt;allratestoday.com/register&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The component — the simplest way
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LocalizedPrice&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-currency-localizer-realtime&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductCard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Premium Plan&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LocalizedPrice&lt;/span&gt;
        &lt;span class="na"&gt;basePrice&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mf"&gt;99.99&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;baseCurrency&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"USD"&lt;/span&gt;
        &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_API_KEY"&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A visitor from Germany sees &lt;code&gt;92.34 €&lt;/code&gt;. A visitor from India sees &lt;code&gt;₹8,321&lt;/code&gt;. A visitor from the US just sees &lt;code&gt;$99.99&lt;/code&gt;. No per-country routing, no SSR detection, no currency-switcher UI to build.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The hook — full control
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;useCurrencyConverter&lt;/code&gt; when you need loading/error states or custom formatting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCurrencyConverter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-currency-localizer-realtime&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductPrice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;convertedPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;localCurrency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCurrencyConverter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;basePrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;baseCurrency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading price...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;$&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt; &lt;span class="c1"&gt;// graceful fallback&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;convertedPrice&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;localCurrency&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Manual override
&lt;/h2&gt;

&lt;p&gt;Want to honor a user-picked currency? Pass it explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LocalizedPrice&lt;/span&gt;
  &lt;span class="na"&gt;basePrice&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mf"&gt;99.99&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;baseCurrency&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"USD"&lt;/span&gt;
  &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"JPY"&lt;/span&gt;           &lt;span class="c1"&gt;// override geolocation&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"YOUR_API_KEY"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful when you have a currency switcher in the header.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just use &lt;code&gt;Intl.NumberFormat&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Intl.NumberFormat&lt;/code&gt; handles &lt;em&gt;formatting&lt;/em&gt;, not &lt;em&gt;conversion&lt;/em&gt;. If you pass it &lt;code&gt;99.99&lt;/code&gt; and tell it to format as JPY, it'll print &lt;code&gt;¥100&lt;/code&gt; — wrong. You still need an actual exchange rate.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;react-currency-localizer-realtime&lt;/code&gt; handles both: detect the currency, fetch the rate, apply it, format the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance notes
&lt;/h2&gt;

&lt;p&gt;Two things usually hurt currency localizers on page load:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Geolocation calls on every render.&lt;/strong&gt; Fixed here with a 24h localStorage cache.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate fetches on every price.&lt;/strong&gt; Fixed here with a 1h in-memory cache shared across component instances.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Net effect: first visit triggers two network calls; every subsequent price on the page (and every return visit within 24h) is instant.&lt;/p&gt;

&lt;p&gt;If a request fails, the component falls back to showing the original price rather than blanking — your customers never see a broken UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-world use case
&lt;/h2&gt;

&lt;p&gt;This is the package I reach for whenever a WooCommerce/Shopify/custom storefront needs per-visitor pricing &lt;em&gt;without&lt;/em&gt; forking the catalog by region. It's the missing middle between "one-currency site" and "separate regional installs."&lt;/p&gt;

&lt;p&gt;Combine it with &lt;code&gt;LocalizedPrice&lt;/code&gt; on product cards and a currency switcher in the header, and you've covered 95% of international-storefront UX in an afternoon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/react-currency-localizer-realtime" rel="noopener noreferrer"&gt;&lt;code&gt;react-currency-localizer-realtime&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Free API key: &lt;a href="https://allratestoday.com/register" rel="noopener noreferrer"&gt;allratestoday.com/register&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;allratestoday.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you ship it on a live store, I'd love to see the before/after conversion numbers — drop them in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by the team behind &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt; — an exchange rate API with real-time mid-market rates for 150+ currencies and the official published rates of 116 central banks and tax authorities, with keyless open endpoints for the central-bank data. Browse the &lt;a href="https://allratestoday.com/docs" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; or &lt;a href="https://allratestoday.com/register/" rel="noopener noreferrer"&gt;grab a free key&lt;/a&gt; to start building.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Open source: official SDKs for &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;JavaScript, Python, PHP, Go and Rust&lt;/a&gt;,&lt;br&gt;
plus an MCP server (&lt;code&gt;@allratestoday/mcp-server&lt;/code&gt;) for AI agents.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow along: &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>ecommerce</category>
      <category>currency</category>
    </item>
    <item>
      <title>Where Does Exchange Rate Data Come From? Sources, Accuracy, and Compliance</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Sat, 19 Sep 2026 19:50:43 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/where-does-exchange-rate-data-come-from-sources-accuracy-and-compliance-n4b</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/where-does-exchange-rate-data-come-from-sources-accuracy-and-compliance-n4b</guid>
      <description>&lt;p&gt;When a developer asks "where does the data come from?", they are usually not asking out of curiosity. They are asking because an auditor, compliance officer, or product manager wants to know if the rates in their application are &lt;strong&gt;legally defensible&lt;/strong&gt;. The data source determines everything: accuracy, update frequency, auditability, and whether you can use it in regulated financial applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Four Tiers of Exchange Rate Data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tier 1: Central Banks (Most Authoritative)
&lt;/h3&gt;

&lt;p&gt;The ECB, Federal Reserve, Bank of England, and other central banks publish official reference rates. These are the gold standard for regulatory and tax reporting.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ECB:&lt;/strong&gt; ~30 currencies, updated daily at 16:00 CET&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Federal Reserve:&lt;/strong&gt; ~25 currencies, updated daily at 12:00 ET&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limitations:&lt;/strong&gt; Very few currencies, once-daily updates, published with delays&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best for:&lt;/strong&gt; Accounting, tax filings, regulatory compliance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tier 2: Licensed Financial Data Providers (Production-Grade)
&lt;/h3&gt;

&lt;p&gt;Refinitiv, Bloomberg, and ICE provide real-time interbank rates sourced directly from Tier 1 banks and market makers. These feeds cost thousands per month when accessed directly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coverage:&lt;/strong&gt; 150–200+ currencies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update frequency:&lt;/strong&gt; Seconds to minutes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data type:&lt;/strong&gt; Mid-market (interbank) rates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best for:&lt;/strong&gt; Trading, payments, e-commerce, any production app&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tier 3: Aggregated / Derived Data (Varies Widely)
&lt;/h3&gt;

&lt;p&gt;Some APIs aggregate rates from multiple unnamed sources, apply their own averaging, or derive rates from commercial services. Quality varies dramatically.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Transparency:&lt;/strong&gt; Often unclear which sources are used&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk:&lt;/strong&gt; May include retail spreads or outdated data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best for:&lt;/strong&gt; Non-critical displays, hobby projects&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tier 4: Scraped / Unverified Data (Not Recommended)
&lt;/h3&gt;

&lt;p&gt;Some free APIs scrape exchange rates from public websites or other APIs. No provenance, no audit trail, may violate terms of service.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reliability:&lt;/strong&gt; Can break without notice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal risk:&lt;/strong&gt; May violate ToS of scraped sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best for:&lt;/strong&gt; Personal projects only&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Major APIs Actually Use
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;API&lt;/th&gt;
&lt;th&gt;Primary Source&lt;/th&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Disclosed?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AllRatesToday&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;institutional interbank market data / Interbank feeds&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Tier 2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frankfurter&lt;/td&gt;
&lt;td&gt;European Central Bank (ECB)&lt;/td&gt;
&lt;td&gt;Tier 1&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Exchange Rates&lt;/td&gt;
&lt;td&gt;"Multiple commercial sources"&lt;/td&gt;
&lt;td&gt;Tier 2–3&lt;/td&gt;
&lt;td&gt;Partially&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ExchangeRate-API&lt;/td&gt;
&lt;td&gt;"Central Banks and financial institutions"&lt;/td&gt;
&lt;td&gt;Tier 1–3&lt;/td&gt;
&lt;td&gt;Partially&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fixer.io&lt;/td&gt;
&lt;td&gt;"ECB and commercial feeds"&lt;/td&gt;
&lt;td&gt;Tier 1–3&lt;/td&gt;
&lt;td&gt;Partially&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CurrencyAPI&lt;/td&gt;
&lt;td&gt;Not specified&lt;/td&gt;
&lt;td&gt;Unknown&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key insight:&lt;/strong&gt; Many APIs use vague language like "multiple commercial sources" without naming them. If you need data that will withstand an audit, look for APIs that explicitly name their sources.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Data Source Matters for Compliance
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Financial Reporting (IFRS / GAAP)
&lt;/h3&gt;

&lt;p&gt;IFRS and GAAP require that exchange rates used in financial statements be traceable to a recognized source. Central Bank rates (Tier 1) are always accepted. Rates from a named provider like Reuters (Tier 2) are typically accepted. Rates from unnamed sources may be challenged by auditors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payment Services (PSD2)
&lt;/h3&gt;

&lt;p&gt;In the EU, PSD2 requires transparency in currency conversion. If you process cross-border payments, you must disclose the exchange rate and its source. Using an API that doesn't disclose its source makes this impossible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tax Reporting
&lt;/h3&gt;

&lt;p&gt;Tax authorities accept Central Bank rates or recognized market rates. Using rates from an undisclosed source could result in rejected filings.&lt;/p&gt;

&lt;h2&gt;
  
  
  How AllRatesToday Sources Its Data
&lt;/h2&gt;

&lt;p&gt;AllRatesToday publishes two kinds of rates. Real-time mid-market rates are aggregated from institutional interbank market data; official rates are collected from the publication of each of 116 central banks and tax authorities (Tier 1). For the real-time feed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source:&lt;/strong&gt; Tier 2 — aggregated institutional interbank market data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate type:&lt;/strong&gt; Mid-market (interbank) — no spread or markup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coverage:&lt;/strong&gt; 160+ currencies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update frequency:&lt;/strong&gt; Every 60 seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparable to:&lt;/strong&gt; the mid-market rate shown by Google Finance and XE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API response includes timestamps for every rate, giving you a verifiable audit trail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-09T14:30:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;For audit trails:&lt;/strong&gt; Store the rate, timestamp, and source currency pair for every conversion your application performs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Choosing the Right Source for Your Use Case
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Recommended Source&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Financial statements&lt;/td&gt;
&lt;td&gt;Central Bank (Tier 1)&lt;/td&gt;
&lt;td&gt;Required by IFRS/GAAP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tax reporting&lt;/td&gt;
&lt;td&gt;Central Bank (Tier 1)&lt;/td&gt;
&lt;td&gt;Accepted by all tax authorities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment processing&lt;/td&gt;
&lt;td&gt;Reuters/Refinitiv (Tier 2)&lt;/td&gt;
&lt;td&gt;Real-time accuracy, named source for PSD2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E-commerce pricing&lt;/td&gt;
&lt;td&gt;Reuters/Refinitiv (Tier 2)&lt;/td&gt;
&lt;td&gt;Live rates prevent margin erosion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashboard / display&lt;/td&gt;
&lt;td&gt;Tier 1 or Tier 2&lt;/td&gt;
&lt;td&gt;Either works&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Questions to Ask Your API Provider
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What is the primary data source?&lt;/strong&gt; Accept named sources (ECB, Reuters, Bloomberg). Be wary of "multiple sources" without specifics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Are the rates mid-market or retail?&lt;/strong&gt; Mid-market = no spread. Retail = hidden markup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How often is the data refreshed from the source?&lt;/strong&gt; Not how fast the API responds — how fresh the underlying data is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can I get a data provenance statement?&lt;/strong&gt; For regulated industries, you may need written confirmation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What happens if the source goes down?&lt;/strong&gt; Stale data, errors, or failover?&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;AllRatesToday&lt;/strong&gt; sources mid-market rates from institutional interbank market data. Named source, timestamped responses, audit-ready data. Free tier available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://allratestoday.com/register" rel="noopener noreferrer"&gt;Get your free API key&lt;/a&gt; | &lt;a href="https://allratestoday.com/developers" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt; | &lt;a href="https://github.com/allratestoday/exchange-rates-api" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by the team behind &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt; — an exchange rate API with real-time mid-market rates for 150+ currencies and the official published rates of 116 central banks and tax authorities, with keyless open endpoints for the central-bank data. Browse the &lt;a href="https://allratestoday.com/docs" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; or &lt;a href="https://allratestoday.com/register/" rel="noopener noreferrer"&gt;grab a free key&lt;/a&gt; to start building.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Open source: official SDKs for &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;JavaScript, Python, PHP, Go and Rust&lt;/a&gt;,&lt;br&gt;
plus an MCP server (&lt;code&gt;@allratestoday/mcp-server&lt;/code&gt;) for AI agents.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow along: &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>fintech</category>
      <category>currency</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Mid-Market vs Retail Exchange Rates: What Developers Need to Know</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Sat, 19 Sep 2026 19:50:40 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/mid-market-vs-retail-exchange-rates-what-developers-need-to-know-10kl</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/mid-market-vs-retail-exchange-rates-what-developers-need-to-know-10kl</guid>
      <description>&lt;p&gt;When you integrate an exchange rate API into your application, one of the most important questions to ask is: &lt;strong&gt;"Is this the mid-market rate or a retail rate?"&lt;/strong&gt; The difference can mean a 1–5% hidden markup on every conversion your users see — and most API documentation doesn't make this clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is the Mid-Market Rate?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;mid-market rate&lt;/strong&gt; (also called the &lt;strong&gt;interbank rate&lt;/strong&gt;) is the midpoint between the buy price and the sell price of a currency pair on the global foreign exchange market. It is the "true" exchange rate — the rate at which banks trade with each other in large volumes.&lt;/p&gt;

&lt;p&gt;When you see an exchange rate on Google, XE, or Bloomberg, you are seeing the mid-market rate.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; If banks are buying EUR at 1.0820 USD and selling EUR at 1.0830 USD, the mid-market rate is &lt;strong&gt;1.0825&lt;/strong&gt; — the midpoint between the two.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Is a Retail Rate?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;retail rate&lt;/strong&gt; is the mid-market rate plus a &lt;strong&gt;spread&lt;/strong&gt; (markup). This spread is how banks, exchange services, and money transfer companies make money.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider Type&lt;/th&gt;
&lt;th&gt;Typical Spread&lt;/th&gt;
&lt;th&gt;Impact on $10,000&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mid-market (interbank)&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Online transfer (e.g. Wise)&lt;/td&gt;
&lt;td&gt;0.3–0.7%&lt;/td&gt;
&lt;td&gt;$30–$70&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bank wire transfer&lt;/td&gt;
&lt;td&gt;1–3%&lt;/td&gt;
&lt;td&gt;$100–$300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Credit card foreign transaction&lt;/td&gt;
&lt;td&gt;1–3%&lt;/td&gt;
&lt;td&gt;$100–$300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Airport currency exchange&lt;/td&gt;
&lt;td&gt;3–8%&lt;/td&gt;
&lt;td&gt;$300–$800&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Matters for Your Application
&lt;/h2&gt;

&lt;p&gt;If your API returns retail rates instead of mid-market rates, you have a transparency problem. Your users might think they are getting the "real" exchange rate, but there is already a hidden markup baked into the data.&lt;/p&gt;

&lt;h3&gt;
  
  
  E-Commerce Price Display
&lt;/h3&gt;

&lt;p&gt;If your online store shows "1 USD = 0.92 EUR" but the real mid-market rate is 0.9350, your international customers are seeing prices that are 1.6% higher than they should be. On a $500 purchase, that is $8 in invisible overcharge.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Currency SaaS Billing
&lt;/h3&gt;

&lt;p&gt;If you bill customers in their local currency using retail rates, you are effectively applying a markup your customers didn't agree to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Financial Reporting
&lt;/h3&gt;

&lt;p&gt;Auditors and compliance teams expect rates traceable to a recognized source. Mid-market rates from Reuters, Bloomberg, or Central Banks are accepted. Retail rates from unnamed sources are not.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Tell What Your API Returns
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compare against Google:&lt;/strong&gt; Search "1 USD to EUR" on Google (mid-market rate). If your API's rate differs by more than 0.05%, it may include a spread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check the documentation:&lt;/strong&gt; Look for "interbank," "mid-market," or "wholesale." If the docs say "indicative rates" or don't specify, be cautious.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask about the source:&lt;/strong&gt; Reuters, Refinitiv, or Bloomberg = mid-market. Unnamed "multiple sources" = potentially includes retail spreads.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Red flag:&lt;/strong&gt; If an exchange rate API is completely free with unlimited requests and doesn't disclose its data source, the data may be low-quality or include a hidden spread.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Adding Your Own Transparent Markup
&lt;/h2&gt;

&lt;p&gt;If your business model requires a spread, start with the mid-market rate and apply your own transparent margin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AllRatesToday&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@allratestoday/sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AllRatesToday&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YOUR_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MARKUP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.005&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 0.5% spread&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCustomerRate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;midMarketRate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customerRate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;midMarketRate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;MARKUP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;midMarket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;midMarketRate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;customerRate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customerRate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;spread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MARKUP&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getCustomerRate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Mid-market: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;midMarket&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Customer rate: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customerRate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (includes &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spread&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;% fee)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach gives you full control over your pricing while being transparent with your users about the markup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Mid-Market Rate&lt;/th&gt;
&lt;th&gt;Retail Rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Definition&lt;/td&gt;
&lt;td&gt;Midpoint between buy/sell&lt;/td&gt;
&lt;td&gt;Mid-market + provider's spread&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Markup&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;0.3% to 8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Used by&lt;/td&gt;
&lt;td&gt;Google, XE, Bloomberg&lt;/td&gt;
&lt;td&gt;Banks, exchange bureaus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for apps&lt;/td&gt;
&lt;td&gt;Price display, invoicing, comparison&lt;/td&gt;
&lt;td&gt;Simulating actual transfer cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit-friendly&lt;/td&gt;
&lt;td&gt;Yes (traceable source)&lt;/td&gt;
&lt;td&gt;Depends on provider&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;strong&gt;AllRatesToday&lt;/strong&gt; provides mid-market rates from institutional interbank market data for 160+ currencies. No hidden spreads, no markup. Free tier available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://allratestoday.com/register" rel="noopener noreferrer"&gt;Get your free API key&lt;/a&gt; | &lt;a href="https://allratestoday.com/developers" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt; | &lt;a href="https://github.com/allratestoday/exchange-rates-api" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by the team behind &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt; — an exchange rate API with real-time mid-market rates for 150+ currencies and the official published rates of 116 central banks and tax authorities, with keyless open endpoints for the central-bank data. Browse the &lt;a href="https://allratestoday.com/docs" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; or &lt;a href="https://allratestoday.com/register/" rel="noopener noreferrer"&gt;grab a free key&lt;/a&gt; to start building.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Open source: official SDKs for &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;JavaScript, Python, PHP, Go and Rust&lt;/a&gt;,&lt;br&gt;
plus an MCP server (&lt;code&gt;@allratestoday/mcp-server&lt;/code&gt;) for AI agents.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow along: &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>currency</category>
      <category>fintech</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Is Oanda API Free? (And What to Use Instead in 2026)</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Mon, 14 Sep 2026 11:15:16 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/is-oanda-api-free-and-what-to-use-instead-in-2026-1445</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/is-oanda-api-free-and-what-to-use-instead-in-2026-1445</guid>
      <description>&lt;p&gt;&lt;strong&gt;Short answer: no.&lt;/strong&gt; Oanda does not offer a free, general-purpose currency API for developers. The widely-cited &lt;strong&gt;v20 REST API&lt;/strong&gt; requires a registered Oanda fxTrade brokerage account, and the separate &lt;strong&gt;Exchange Rates Data API&lt;/strong&gt; is paid-only with no permanent free tier.&lt;/p&gt;

&lt;p&gt;If you landed here because you searched "free Oanda API," you almost certainly don't want what Oanda actually sells. This guide explains what each Oanda API really is, who it's for, why most developers end up looking elsewhere, and which alternatives give you real-time FX data without the brokerage account or enterprise contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Oanda APIs (They're Not the Same Product)
&lt;/h2&gt;

&lt;p&gt;The first thing to understand is that "the Oanda API" is two completely different products with different audiences and access models.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Oanda v20 REST API (for traders)
&lt;/h3&gt;

&lt;p&gt;The v20 API is the programmatic interface to Oanda's &lt;strong&gt;fxTrade&lt;/strong&gt; brokerage platform. It exposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live bid/ask prices on the instruments your account is permitted to trade&lt;/li&gt;
&lt;li&gt;Order placement, modification, and cancellation&lt;/li&gt;
&lt;li&gt;Position and trade management&lt;/li&gt;
&lt;li&gt;Account history and transaction logs&lt;/li&gt;
&lt;li&gt;Streaming price and event endpoints over HTTP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To call it, you need an &lt;strong&gt;fxTrade account ID and a personal access token&lt;/strong&gt;, both issued by Oanda after you register. There are two flavors of token:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Practice (demo) tokens&lt;/strong&gt; — work against &lt;code&gt;api-fxpractice.oanda.com&lt;/code&gt; with simulated funds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live tokens&lt;/strong&gt; — work against &lt;code&gt;api-fxtrade.oanda.com&lt;/code&gt; with real funds in your funded account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The v20 API itself doesn't have a per-call price tag, but you cannot use it without an Oanda account, and the live environment requires the same KYC, residency checks, and (in many regions) minimum deposits as opening any brokerage account. It is &lt;em&gt;not&lt;/em&gt; a developer-tier currency data API in the way that ExchangeRate-API or AllRatesToday are.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Oanda Exchange Rates API (for businesses)
&lt;/h3&gt;

&lt;p&gt;The Exchange Rates Data API is Oanda's standalone &lt;strong&gt;commercial data product&lt;/strong&gt;, sold separately from fxTrade. It targets enterprises that need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Audit-grade historical FX rates (back to 1990 for some pairs)&lt;/li&gt;
&lt;li&gt;Daily, hourly, or minute-level snapshots&lt;/li&gt;
&lt;li&gt;Specific quote types (bid, ask, mid, highlow)&lt;/li&gt;
&lt;li&gt;Multi-currency reporting for ERP systems and tax compliance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This product has &lt;strong&gt;no free tier and no public pricing&lt;/strong&gt;. Access is through an annual sales contract negotiated based on coverage, frequency, and call volume. Public reports and customer disclosures place entry pricing in the hundreds of dollars per month and up — comparable to XE Currency Data API or Refinitiv's lower-tier feeds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Developers Can't (or Shouldn't) Use Oanda
&lt;/h2&gt;

&lt;p&gt;If you just want to convert USD to EUR in your app, or display live rates on a SaaS dashboard, Oanda is almost always the wrong tool. Here's why developers keep walking away:&lt;/p&gt;

&lt;h3&gt;
  
  
  You need a brokerage account for the v20 API
&lt;/h3&gt;

&lt;p&gt;To get a v20 access token, you have to &lt;strong&gt;register an Oanda fxTrade account&lt;/strong&gt;, complete KYC, and in some regions deposit funds. Even the demo path requires identity verification. You can't get a token in five minutes the way you can with most public REST APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  The v20 API isn't designed for general-purpose conversion
&lt;/h3&gt;

&lt;p&gt;The v20 endpoints are built around the concept of &lt;em&gt;your account&lt;/em&gt;: prices for instruments you're allowed to trade, in the account currency you opened with. There is no clean "give me USD/EUR mid-market right now" call without first assembling instrument lists and parsing tradeable prices. It works, but it's overkill for a converter widget.&lt;/p&gt;

&lt;h3&gt;
  
  
  Geofencing and regional restrictions
&lt;/h3&gt;

&lt;p&gt;Oanda is regulated in multiple jurisdictions and not every account type is available everywhere. Developers in some countries can't open a live fxTrade account at all, which means no live token, which means no production v20 access. Demo access is broader but still subject to regional availability.&lt;/p&gt;

&lt;h3&gt;
  
  
  2026 free-tier restrictions
&lt;/h3&gt;

&lt;p&gt;Over the past 12–18 months, Oanda has tightened access on multiple surfaces — including stricter KYC for new fxTrade accounts, region-specific fee schedules, and a rebrand of the data API away from the older "fxTrade Data" naming. The pattern is the same one we've seen at XE, CurrencyLayer, and others: legacy free or low-tier endpoints are quietly retired in favor of paid plans.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Exchange Rates API is sold to procurement, not developers
&lt;/h3&gt;

&lt;p&gt;If you have to email sales, sign an NDA, and wait two weeks for a quote, you're not in the developer-API market — you're in the enterprise data market. That's fine if you're a bank. It's the wrong shape for a startup, side project, or open-source library.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "Free Oanda API" Searches Actually Want
&lt;/h2&gt;

&lt;p&gt;When developers Google "is Oanda API free," what they almost always mean is one of three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;"Can I get live FX rates without paying?"&lt;/strong&gt; — Yes, with a permanent free tier from a developer-first API. Oanda is the wrong starting point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Can I build a currency converter / SaaS pricing localizer / accounting app for free?"&lt;/strong&gt; — Yes, with sub-second to 60-second mid-market rates, full historical data, and no credit card required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Can I do paper trading / strategy backtests for free?"&lt;/strong&gt; — Use the Oanda v20 API in &lt;em&gt;demo mode&lt;/em&gt;. That's its actual free use case, but you'll still need to register a practice account.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're in the first two camps, you don't need Oanda. You need a developer-first FX data API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Oanda Alternatives for Developers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Permanent Free Tier&lt;/th&gt;
&lt;th&gt;Real-Time Updates&lt;/th&gt;
&lt;th&gt;Trading?&lt;/th&gt;
&lt;th&gt;Account Required&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AllRatesToday&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;60-second mid-market&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Email signup, no card&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Oanda v20&lt;/td&gt;
&lt;td&gt;Demo only&lt;/td&gt;
&lt;td&gt;Tick-level on tradeable pairs&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;fxTrade account + KYC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Oanda Exchange Rates&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Configurable, paid&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Annual sales contract&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ExchangeRate-API&lt;/td&gt;
&lt;td&gt;Yes (limited)&lt;/td&gt;
&lt;td&gt;Daily on free, hourly on paid&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;API key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CurrencyLayer&lt;/td&gt;
&lt;td&gt;100 req/mo, USD only&lt;/td&gt;
&lt;td&gt;Hourly free, 60s on paid&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;API key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fixer.io&lt;/td&gt;
&lt;td&gt;100 req/mo, EUR only&lt;/td&gt;
&lt;td&gt;Hourly free, 60s on paid&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;API key&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For pure currency data — conversions, historical rates, SaaS pricing localization, accounting integrations, dashboards — &lt;strong&gt;AllRatesToday&lt;/strong&gt; is the practical replacement. Same institutional-grade data feed Oanda's data product is built on, exposed as a clean REST API with a permanent free tier, official SDKs for JavaScript / Python / PHP, and an MCP server for AI agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Oanda &lt;em&gt;Is&lt;/em&gt; the Right Choice
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You're building an automated &lt;strong&gt;trading bot&lt;/strong&gt; or systematic strategy and need order execution, not just prices.&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;tick-level streaming&lt;/strong&gt; on a specific set of forex / CFD instruments tied to a real funded account.&lt;/li&gt;
&lt;li&gt;You're an enterprise with a procurement budget and need &lt;strong&gt;audit-grade historical data&lt;/strong&gt; that names Oanda as the source.&lt;/li&gt;
&lt;li&gt;You already have an Oanda relationship for retail FX and want a single vendor.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Skip Oanda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You only need &lt;strong&gt;currency conversions&lt;/strong&gt; in an app, dashboard, invoice, or report.&lt;/li&gt;
&lt;li&gt;You want &lt;strong&gt;fast onboarding&lt;/strong&gt; — minutes, not weeks.&lt;/li&gt;
&lt;li&gt;You don't want to &lt;strong&gt;open a brokerage account&lt;/strong&gt; to call an API.&lt;/li&gt;
&lt;li&gt;You need a &lt;strong&gt;free tier&lt;/strong&gt; for prototyping, hobby projects, or open-source.&lt;/li&gt;
&lt;li&gt;You want &lt;strong&gt;predictable monthly pricing&lt;/strong&gt;, not annual enterprise contracts.&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;CORS&lt;/strong&gt; for browser-side calls (the v20 API is server-side only).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Drop-in Replacement Example
&lt;/h2&gt;

&lt;p&gt;Here's the same "USD to EUR conversion" call against AllRatesToday — no brokerage account, no contract, no KYC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://api.allratestoday.com/v1/convert?from=USD&amp;amp;to=EUR&amp;amp;amount=100"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_API_KEY"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EUR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.9234&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;92.34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-30T18:22:11Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replacing the v20 instrument-pricing flow takes about ten minutes. Replacing the Exchange Rates Data API for historical lookups takes the same. The free tier covers most prototypes outright; paid plans start far below Oanda's enterprise floor.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is the Oanda API free?
&lt;/h3&gt;

&lt;p&gt;No. The v20 REST API requires a registered fxTrade brokerage account (live or demo), and the Exchange Rates Data API is a paid product with no permanent free tier. There is no general-purpose free developer plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use the Oanda API without a trading account?
&lt;/h3&gt;

&lt;p&gt;Not the v20 API. It's tied to your fxTrade account credentials and is intended for executing trades or pulling data tied to that account. The Exchange Rates Data API is separate and does not require a trading account, but it is paid-only.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is the Oanda demo account API free?
&lt;/h3&gt;

&lt;p&gt;Yes — demo (practice) accounts can access the v20 API at no cost, but they're meant for testing trading strategies. They have rate limits, are subject to availability, and the rates may differ slightly from production. Demo access is not a substitute for a production data feed.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does the Oanda Exchange Rates API cost?
&lt;/h3&gt;

&lt;p&gt;Oanda does not publish list pricing publicly. The product is sold per-quote with annual contracts, and pricing is negotiated based on volume, currency coverage, and update frequency. Public reports place entry pricing in the hundreds of dollars per month and up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is there a free alternative to the Oanda API?
&lt;/h3&gt;

&lt;p&gt;Yes. &lt;a href="https://allratestoday.com/" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt; offers a permanent free tier with real-time mid-market rates, 160+ currencies, historical data, and no credit card required. It's the closest free equivalent for developers who don't need Oanda's trade execution capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use Oanda data in a commercial product?
&lt;/h3&gt;

&lt;p&gt;Yes, on paid plans of either the v20 or Exchange Rates products, subject to Oanda's licensing terms. The demo / practice environment is generally not licensed for commercial redistribution — read the terms before shipping.&lt;/p&gt;




&lt;p&gt;If you searched for a free Oanda API, you don't actually need Oanda — you need &lt;strong&gt;real-time mid-market FX rates with a developer-friendly free tier&lt;/strong&gt;. &lt;a href="https://allratestoday.com/" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt; ships exactly that, with official SDKs and an MCP server for AI agents. No brokerage account required.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by the team behind &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt; — an exchange rate API&lt;br&gt;
with real-time mid-market rates for 160+ currencies and the official published tables of&lt;br&gt;
116 central banks and tax authorities. The official-rate endpoint needs no key. Browse the&lt;br&gt;
&lt;a href="https://allratestoday.com/docs" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; or &lt;a href="https://allratestoday.com/register/" rel="noopener noreferrer"&gt;grab a free key&lt;/a&gt;&lt;br&gt;
to start building.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Open source: official SDKs for &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;JavaScript, Python, PHP, Go and Rust&lt;/a&gt;,&lt;br&gt;
plus MCP servers and a hosted MCP endpoint at &lt;code&gt;https://allratestoday.com/api/mcp&lt;/code&gt; for AI agents.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>fintech</category>
      <category>currency</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How Often Are Exchange Rates Updated? Real-Time vs Daily Explained</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Mon, 14 Sep 2026 11:15:15 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/how-often-are-exchange-rates-updated-real-time-vs-daily-explained-g6p</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/how-often-are-exchange-rates-updated-real-time-vs-daily-explained-g6p</guid>
      <description>&lt;p&gt;"How often are the rates updated?" is the single most asked question about exchange rate APIs. It shows up in every API's FAQ, every developer forum thread, and every Stack Overflow comparison. And for good reason — the answer determines whether an API is suitable for your project or a liability waiting to happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Layers of "Update Frequency"
&lt;/h2&gt;

&lt;p&gt;When an API says "rates updated every X," that statement hides three separate concerns.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Real-Time vs Delayed Data
&lt;/h3&gt;

&lt;p&gt;The forex market trades 24 hours a day, 5 days a week. Currency prices change every second. An API's update frequency tells you how closely it tracks those changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time (seconds to minutes):&lt;/strong&gt; Pulls from live interbank market feeds. Essential for trading, payments, and any app where a 1% swing matters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hourly:&lt;/strong&gt; A middle ground. Acceptable for dashboards and reporting, but misses intraday volatility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily:&lt;/strong&gt; A single snapshot, usually from the ECB at 16:00 CET. Fine for accounting and invoicing.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; On March 11, 2026, GBP/USD moved from 1.2910 to 1.2745 within 6 hours after an unexpected Bank of England announcement. An app using daily rates would have shown a price that was off by 1.3% for the entire day — a $13 discrepancy on every $1,000 transaction.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. The "Free Tier" Trap
&lt;/h3&gt;

&lt;p&gt;Most exchange rate APIs advertise real-time capabilities but lock them behind paid plans. Here is what free tiers actually deliver:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;API&lt;/th&gt;
&lt;th&gt;Free Tier Update&lt;/th&gt;
&lt;th&gt;Paid Tier Update&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AllRatesToday&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Every 60 seconds&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Every 60 seconds&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open Exchange Rates&lt;/td&gt;
&lt;td&gt;Hourly&lt;/td&gt;
&lt;td&gt;Every 5 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fixer.io&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Every 60 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ExchangeRate-API&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CurrencyAPI&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Hourly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frankfurter&lt;/td&gt;
&lt;td&gt;Daily (ECB)&lt;/td&gt;
&lt;td&gt;N/A (free only)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice the pattern: most free tiers give you &lt;strong&gt;daily rates only&lt;/strong&gt;. You build your app, test it, ship it — and then discover during market volatility that your "exchange rate feature" is showing yesterday's price.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AllRatesToday is different:&lt;/strong&gt; The free tier gets the same 60-second update frequency as paid plans. The only limit is request volume, not data freshness.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Accuracy vs Latency: What Does "Real-Time" Actually Mean?
&lt;/h3&gt;

&lt;p&gt;This is the subtlety most developers miss. "Real-time" can mean two very different things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time source:&lt;/strong&gt; The underlying data comes from live institutional interbank feeds. The rate itself is current.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time delivery:&lt;/strong&gt; The API responds quickly, but the data might be a cached snapshot from hours ago. Fast delivery, stale data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always ask: &lt;strong&gt;"Is the data real-time, or just the API response?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AllRatesToday sources data from &lt;strong&gt;institutional interbank market data&lt;/strong&gt; and interbank market feeds — the same sources used by Google Finance, XE, and Bloomberg.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Update Frequency Do You Actually Need?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Minimum Update&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Trading / Forex&lt;/td&gt;
&lt;td&gt;Real-time (seconds)&lt;/td&gt;
&lt;td&gt;Price slippage directly costs money&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment processing&lt;/td&gt;
&lt;td&gt;Real-time (minutes)&lt;/td&gt;
&lt;td&gt;Conversion at checkout must reflect current market&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E-commerce price display&lt;/td&gt;
&lt;td&gt;Hourly to real-time&lt;/td&gt;
&lt;td&gt;Stale rates erode margins or overcharge customers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SaaS multi-currency billing&lt;/td&gt;
&lt;td&gt;Daily to hourly&lt;/td&gt;
&lt;td&gt;Invoices are usually generated at intervals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accounting / Tax reporting&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Regulatory bodies accept end-of-day rates&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  How to Verify an API's Update Frequency
&lt;/h2&gt;

&lt;p&gt;Don't take marketing claims at face value. Here is a simple test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fetch the rate, wait 2 minutes, fetch again&lt;/span&gt;
&lt;span class="c"&gt;# Compare the timestamps and values&lt;/span&gt;

curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://allratestoday.com/api/v1/rates?source=USD&amp;amp;target=EUR"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.time, .rate'&lt;/span&gt;

&lt;span class="nb"&gt;sleep &lt;/span&gt;120

curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://allratestoday.com/api/v1/rates?source=USD&amp;amp;target=EUR"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer YOUR_API_KEY"&lt;/span&gt; | jq &lt;span class="s1"&gt;'.time, .rate'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the timestamps are different and the rate has changed (even slightly), the API is genuinely updating. If both calls return the exact same timestamp, you are getting cached daily data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Daily rates&lt;/strong&gt; are fine for accounting and reporting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hourly rates&lt;/strong&gt; work for dashboards and non-transactional displays.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time rates&lt;/strong&gt; are essential for payments, e-commerce, and anything where money changes hands.&lt;/li&gt;
&lt;li&gt;Most free APIs give you daily data. Check the fine print before building on top of it.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;AllRatesToday&lt;/strong&gt; updates every 60 seconds from institutional interbank market data — even on the free plan. 160+ currencies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://allratestoday.com/register" rel="noopener noreferrer"&gt;Get your free API key&lt;/a&gt; | &lt;a href="https://allratestoday.com/developers" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt; | &lt;a href="https://github.com/allratestoday/exchange-rates-api" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Written by the team behind &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt; — an exchange rate API&lt;br&gt;
with real-time mid-market rates for 160+ currencies and the official published tables of&lt;br&gt;
116 central banks and tax authorities. The official-rate endpoint needs no key. Browse the&lt;br&gt;
&lt;a href="https://allratestoday.com/docs" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; or &lt;a href="https://allratestoday.com/register/" rel="noopener noreferrer"&gt;grab a free key&lt;/a&gt;&lt;br&gt;
to start building.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Open source: official SDKs for &lt;a href="https://github.com/AllRates-Today" rel="noopener noreferrer"&gt;JavaScript, Python, PHP, Go and Rust&lt;/a&gt;,&lt;br&gt;
plus MCP servers and a hosted MCP endpoint at &lt;code&gt;https://allratestoday.com/api/mcp&lt;/code&gt; for AI agents.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>currency</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>15.6 million official exchange rates from 121 central banks and 3 tax authorities, now on Hugging Face</title>
      <dc:creator>viraj geeth</dc:creator>
      <pubDate>Mon, 14 Sep 2026 11:14:41 +0000</pubDate>
      <link>https://dev.to/viraj_geeth_e6dc448fe4d43/146-million-official-exchange-rates-from-107-central-banks-and-tax-authorities-now-on-hugging-face-4nel</link>
      <guid>https://dev.to/viraj_geeth_e6dc448fe4d43/146-million-official-exchange-rates-from-107-central-banks-and-tax-authorities-now-on-hugging-face-4nel</guid>
      <description>&lt;p&gt;If you have ever needed "the ECB rate on the invoice date" for a tax return, a customs form, a transfer-pricing file or an audit, you know the problem. The number exists. It is public. And it is scattered across a hundred central-bank websites, each with its own PDF, XML feed, Excel download or HTML table, each with its own idea of which way round a rate should be quoted.&lt;/p&gt;

&lt;p&gt;We spent most of this year collecting those tables into one pipeline. As of this week the full history is a public dataset on Hugging Face:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://huggingface.co/datasets/AllRates/central-bank-exchange-rates" rel="noopener noreferrer"&gt;https://huggingface.co/datasets/AllRates/central-bank-exchange-rates&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rows&lt;/td&gt;
&lt;td&gt;15,653,091&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Institutions&lt;/td&gt;
&lt;td&gt;121 central banks + 3 tax authorities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Earliest date&lt;/td&gt;
&lt;td&gt;1914 (Swiss National Bank)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Currencies&lt;/td&gt;
&lt;td&gt;215 base, 202 quote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refresh&lt;/td&gt;
&lt;td&gt;daily, from the GitHub source repo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;CC BY-NC 4.0 (non-commercial, attribution)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size&lt;/td&gt;
&lt;td&gt;515 MB CSV, auto-converted to Parquet&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why "official" rates and not market rates
&lt;/h2&gt;

&lt;p&gt;Most exchange-rate datasets are market data: a mid-market snapshot from some aggregator at some time of day. That is the right thing for a price display. It is the wrong thing for anything a regulator will look at.&lt;/p&gt;

&lt;p&gt;Tax offices, customs agencies and accounting standards usually name a publisher. HMRC publishes monthly rates for UK VAT and customs. The ECB reference rate is the default for euro-area statutory reporting. The Reserve Bank of India reference rate is the benchmark for statutory rupee conversions. The Reserve Bank of Australia, Bank of Canada, Banco Central do Brasil and dozens of others publish a daily fixing that is &lt;em&gt;the&lt;/em&gt; rate for that jurisdiction, regardless of what the interbank market did five minutes later.&lt;/p&gt;

&lt;p&gt;Those numbers are not derivable from market data. They have to be collected from the source, on the source's schedule, in the source's convention. That is what this dataset is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is in it
&lt;/h2&gt;

&lt;p&gt;One CSV per institution under &lt;code&gt;rates/&lt;/code&gt;, five columns, identical everywhere:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;ISO 8601 publication date. Weekends and the publisher's holidays are simply absent.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;base&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;The currency being priced (ISO 4217).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;quote&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;The currency it is priced in.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;type&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;The publisher's own label: &lt;code&gt;reference&lt;/code&gt;, &lt;code&gt;middle&lt;/code&gt;, &lt;code&gt;buy&lt;/code&gt;, &lt;code&gt;sell&lt;/code&gt;, &lt;code&gt;spot&lt;/code&gt;, &lt;code&gt;indicative&lt;/code&gt;, &lt;code&gt;monthly&lt;/code&gt;, &lt;code&gt;monthly_average&lt;/code&gt;, &lt;code&gt;quarterly&lt;/code&gt;, &lt;code&gt;close&lt;/code&gt;, and a few more.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;float&lt;/td&gt;
&lt;td&gt;How many &lt;code&gt;quote&lt;/code&gt; one &lt;code&gt;base&lt;/code&gt; buys.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few rows from &lt;code&gt;rates/ecb.csv&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;date,base,quote,type,value
2025-01-02,EUR,AUD,reference,1.6618
2025-01-02,EUR,BGN,reference,1.9558
2025-01-02,EUR,BRL,reference,6.42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alongside the history there is &lt;code&gt;latest/&amp;lt;code&amp;gt;.json&lt;/code&gt; with each institution's most recent table, and &lt;code&gt;sources.json&lt;/code&gt; with the institution's name, country, home currency, kind (central bank or tax authority) and the URL of the page we collect from.&lt;/p&gt;

&lt;p&gt;Coverage by depth, to give you a sense of what "back to 1914" actually means:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Institution&lt;/th&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;First year in dataset&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Swiss National Bank&lt;/td&gt;
&lt;td&gt;&lt;code&gt;snb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1914&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bank of Korea&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bok&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1964&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bank of Israel&lt;/td&gt;
&lt;td&gt;&lt;code&gt;boi&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1975&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hong Kong Monetary Authority&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hkma&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1981&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bank of Japan&lt;/td&gt;
&lt;td&gt;&lt;code&gt;boj&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1998&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;European Central Bank&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ecb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1999&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reserve Bank of India&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rbi&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2003&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;People's Bank of China&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pboc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2006&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most institutions only publish a few years of history on their own sites. Where a bank offered more, we took all of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loading it
&lt;/h2&gt;

&lt;p&gt;With the &lt;code&gt;datasets&lt;/code&gt; library, the whole thing as one table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dataset&lt;/span&gt;

&lt;span class="n"&gt;ds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_dataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AllRates/central-bank-exchange-rates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With pandas, one institution at a time. This is usually what you want, because 15.6 million rows is a lot of memory for a question about one bank:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;ecb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hf://datasets/AllRates/central-bank-exchange-rates/rates/ecb.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;parse_dates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;usd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ecb&lt;/span&gt;&lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;ecb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EUR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ecb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;USD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="nf"&gt;set_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Polars, lazily, if you want to scan several banks without loading all of them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;polars&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pl&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scan_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hf://datasets/AllRates/central-bank-exchange-rates/rates/*.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;col&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;USD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;col&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quote&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With DuckDB, straight off the Hub, no download step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;INSTALL&lt;/span&gt; &lt;span class="n"&gt;httpfs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;LOAD&lt;/span&gt; &lt;span class="n"&gt;httpfs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'hf://datasets/AllRates/central-bank-exchange-rates/rates/rbi.csv'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'USD'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'INR'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'reference'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Three things you can do with it that you could not do before
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Compare what different central banks say the same pair is worth.&lt;/strong&gt; The ECB publishes EUR→USD. The Fed publishes USD→EUR. The Bank of Canada publishes both against CAD. On any given day these disagree by a few basis points because they fix at different times. That spread is itself interesting, and until now you had to scrape three sites to see it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reconstruct a filing exactly.&lt;/strong&gt; Pick the publisher your jurisdiction names, filter to &lt;code&gt;type == "reference"&lt;/code&gt; (or whatever that publisher calls its headline rate), take the row for the invoice date. If the date is missing, the publisher did not publish that day, and your local rule will say whether to use the previous or next business day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Train on a century of official fixings.&lt;/strong&gt; The SNB series runs from 1914. The Bank of Korea from 1964. If you are building anything that needs long, clean, non-market FX series, this is a larger and more consistent corpus than we could find anywhere else in the open.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conventions and caveats
&lt;/h2&gt;

&lt;p&gt;We made a few decisions that you should know about before relying on the data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Direction follows the publisher.&lt;/strong&gt; If the ECB says 1 EUR = 1.0850 USD, that is the row: &lt;code&gt;EUR,USD,reference,1.0850&lt;/code&gt;. We do not flip rates, and we do not compute crosses. If a bank does not publish GBP against JPY, there is no GBP/JPY row for that bank.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;type&lt;/code&gt; is the publisher's label, normalised only in spelling.&lt;/strong&gt; A &lt;code&gt;buy&lt;/code&gt; rate from one bank and a &lt;code&gt;buy&lt;/code&gt; rate from another are not guaranteed to mean the same thing. Read the source page linked in &lt;code&gt;sources.json&lt;/code&gt; if it matters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gaps are real.&lt;/strong&gt; A missing date means the institution did not publish, or published something our collector could not parse and our validation rejected. We would rather have a hole than a wrong number.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every row went through a cross-source plausibility check&lt;/strong&gt; before it was committed. Values that disagree with the rest of the world by more than a threshold are quarantined and reviewed by hand. That caught a handful of unit errors during the backfill, which is why we trust the rest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify before you file.&lt;/strong&gt; The figures are public information republished under CC BY-NC 4.0. For anything legal or tax-related, the original publisher's page is the authority, and it is linked from &lt;code&gt;sources.json&lt;/code&gt; for every institution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it stays current
&lt;/h2&gt;

&lt;p&gt;The dataset is a mirror of a GitHub repository, &lt;a href="https://github.com/AllRates-Today/central-bank-exchange-rates" rel="noopener noreferrer"&gt;AllRates-Today/central-bank-exchange-rates&lt;/a&gt;, which is itself fed by the collection pipeline behind &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;AllRatesToday&lt;/a&gt;. A scheduled Action runs four times a day, pulls each institution's latest table from a keyless open endpoint, commits only when something changed, and then pushes the consolidated per-institution CSVs to Hugging Face. So the Hub copy is never more than a few hours behind the source sites.&lt;/p&gt;

&lt;p&gt;If you want the same data as small JSON files on a CDN instead of a 500 MB dataset, the GitHub repo serves &lt;code&gt;data/latest.json&lt;/code&gt; and per-bank &lt;code&gt;latest.json&lt;/code&gt; over jsDelivr with no key. If you want it as an API with a query language, the same rates are behind &lt;code&gt;https://allratestoday.com/api/open/central-bank/&amp;lt;code&amp;gt;&lt;/code&gt;, also keyless.&lt;/p&gt;

&lt;h2&gt;
  
  
  License
&lt;/h2&gt;

&lt;p&gt;CC BY-NC 4.0. Use it for research, teaching, personal projects and journalism, redistribute it, train on it, with visible credit to AllRatesToday linking to &lt;a href="https://allratestoday.com" rel="noopener noreferrer"&gt;https://allratestoday.com&lt;/a&gt;. Commercial use is not covered by the licence; the Official Rates plan at &lt;a href="https://allratestoday.com/pricing#official" rel="noopener noreferrer"&gt;https://allratestoday.com/pricing#official&lt;/a&gt; is the commercial route, or write to &lt;a href="mailto:support@allratestoday.com"&gt;support@allratestoday.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you build something with it, open an issue on the GitHub repo or leave a note in the dataset's Community tab. Missing an institution you need? The repo README lists how new sources get added, and we are actively expanding coverage.&lt;/p&gt;

</description>
      <category>dataset</category>
      <category>finance</category>
      <category>python</category>
      <category>opendata</category>
    </item>
  </channel>
</rss>
