<?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: Waveleta</title>
    <description>The latest articles on DEV Community by Waveleta (@waveleta).</description>
    <link>https://dev.to/waveleta</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%2F4166179%2F3b0e3bba-af5b-4802-b5e9-6bb4e0db80c3.png</url>
      <title>DEV Community: Waveleta</title>
      <link>https://dev.to/waveleta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/waveleta"/>
    <language>en</language>
    <item>
      <title>FX reference rates vs intraday quotes: which one does your project need?</title>
      <dc:creator>Waveleta</dc:creator>
      <pubDate>Tue, 06 Oct 2026 12:27:22 +0000</pubDate>
      <link>https://dev.to/waveleta/fx-reference-rates-vs-intraday-quotes-which-one-does-your-project-need-52hh</link>
      <guid>https://dev.to/waveleta/fx-reference-rates-vs-intraday-quotes-which-one-does-your-project-need-52hh</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://waveleta.com/blog/fx-reference-rates-vs-intraday" rel="noopener noreferrer"&gt;waveleta.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When developers ask me about FX data for the &lt;strong&gt;Waveleta Developer API&lt;/strong&gt;, the first question is usually "does it update tick by tick?". The honest answer is no: Waveleta provides &lt;strong&gt;daily FX reference rates&lt;/strong&gt;, refreshed each business day. For a surprising number of projects, that's exactly what you want. Here's the difference, and how to tell which one you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an FX reference rate?
&lt;/h2&gt;

&lt;p&gt;A reference rate is a single, official-style exchange rate for a currency pair, published once per business day. It's a snapshot that everyone can point to: "the EUR/USD rate on 6 October was X".&lt;/p&gt;

&lt;p&gt;Reference rates are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stable:&lt;/strong&gt; one value per pair per business day, so everyone using it gets the same number.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy to cite:&lt;/strong&gt; you can say exactly which date a rate is from.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Informational:&lt;/strong&gt; they're for information, reporting and conversion, not for live pricing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is an intraday quote?
&lt;/h2&gt;

&lt;p&gt;An intraday quote changes throughout the day, often many times per second. It reflects the current market price at a given venue. Intraday data is what you need if the exact minute matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one do you need?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your project&lt;/th&gt;
&lt;th&gt;Reference rates&lt;/th&gt;
&lt;th&gt;Intraday&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Currency converter on a blog or shop&lt;/td&gt;
&lt;td&gt;✅ Ideal&lt;/td&gt;
&lt;td&gt;Overkill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invoices, expenses, accounting&lt;/td&gt;
&lt;td&gt;✅ Ideal (date-stamped)&lt;/td&gt;
&lt;td&gt;Not needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monthly or weekly reports&lt;/td&gt;
&lt;td&gt;✅ Ideal&lt;/td&gt;
&lt;td&gt;Not needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Rate of the day" widget&lt;/td&gt;
&lt;td&gt;✅ Ideal&lt;/td&gt;
&lt;td&gt;Not needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Travel budget apps&lt;/td&gt;
&lt;td&gt;✅ Good fit&lt;/td&gt;
&lt;td&gt;Not needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anything that depends on minute-by-minute prices&lt;/td&gt;
&lt;td&gt;❌ Not suitable&lt;/td&gt;
&lt;td&gt;Needed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If your users would be happy with "today's rate", reference rates are simpler, cheaper to serve and easier to explain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why daily rates are easier to build on
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cache all day.&lt;/strong&gt; The rate only changes once per business day, so you can cache aggressively. With the Waveleta API at €0.002 per call, a converter that refreshes FX twice a day costs about €0.12 a month.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No confusing flicker.&lt;/strong&gt; Users don't see a number change while they're reading it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear dating.&lt;/strong&gt; Each rate comes with the date it applies to (&lt;code&gt;as_of_date&lt;/code&gt; in the Waveleta API), so you can show "rate as of 6 Oct".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekends and holidays are predictable.&lt;/strong&gt; No new rate is published on non-business days. Show the latest available date and you're done.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How FX works in the Waveleta API
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;GET /v1/fx/rates&lt;/code&gt; returns the current daily reference rate for each supported pair, with the pair, base and quote currencies, the rate and its date. FX is in early access in Waveleta, and the data is daily reference rates only, refreshed each business day. There's no intraday FX.&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="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$WAVELETA_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://api.waveleta.com/v1/fx/rates?limit=20"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full Python and JavaScript examples are in the &lt;a href="https://waveleta.com/blog/waveleta-api-python-javascript" rel="noopener noreferrer"&gt;Waveleta API quickstart&lt;/a&gt;. On WordPress, the Waveleta WordPress plugin has a ready-made FX table and currency converter: see the &lt;a href="https://waveleta.com/developer/wordpress" rel="noopener noreferrer"&gt;Waveleta WordPress guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pricing is prepaid: €20 minimum top-up, then €0.002 per call. &lt;a href="https://waveleta.com/developer/join" rel="noopener noreferrer"&gt;Sign up here&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Are Waveleta FX rates intraday?&lt;/strong&gt;&lt;br&gt;
No. They're daily reference rates, refreshed each business day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens at weekends?&lt;/strong&gt;&lt;br&gt;
No new reference rate is published on non-business days. The API returns the most recent available rate and its date.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use reference rates for a currency converter?&lt;/strong&gt;&lt;br&gt;
Yes. That's one of the best uses for them. Show the date next to the result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use them as live market prices?&lt;/strong&gt;&lt;br&gt;
No. Reference rates are for information, reporting and conversion only.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Informational only, not financial advice. Waveleta is not a broker.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>fintech</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Getting started with the Waveleta API in Python and JavaScript</title>
      <dc:creator>Waveleta</dc:creator>
      <pubDate>Tue, 06 Oct 2026 12:19:34 +0000</pubDate>
      <link>https://dev.to/waveleta/getting-started-with-the-waveleta-api-in-python-and-javascript-12ie</link>
      <guid>https://dev.to/waveleta/getting-started-with-the-waveleta-api-in-python-and-javascript-12ie</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://waveleta.com/blog/waveleta-api-python-javascript" rel="noopener noreferrer"&gt;waveleta.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is a hands-on quickstart for the &lt;strong&gt;Waveleta Developer API&lt;/strong&gt;: one request in curl, then working examples in Python and JavaScript for crypto prices, FX reference rates and commodities, along with clean error handling. If you haven't read it yet, the &lt;a href="https://waveleta.com/blog/waveleta-developer-api" rel="noopener noreferrer"&gt;Waveleta API overview&lt;/a&gt; explains pricing (prepaid, €0.002 per call, €20 minimum top-up).&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;p&gt;You need an API key. Sign up at &lt;a href="https://waveleta.com/developer/join" rel="noopener noreferrer"&gt;waveleta.com/developer/join&lt;/a&gt;, confirm your email, top up €20 and create a key. Keys look like &lt;code&gt;wl_…&lt;/code&gt;. Keep it out of your source code: store it in an environment variable.&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="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;WAVELETA_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"wl_your_key_here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The base URL is &lt;code&gt;https://api.waveleta.com&lt;/code&gt;. Authenticate with either header:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Authorization: Bearer wl_…&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-Api-Key: wl_…&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Your first request (curl)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$WAVELETA_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://api.waveleta.com/v1/crypto/tickers?limit=3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is JSON with an &lt;code&gt;ok&lt;/code&gt; flag, a &lt;code&gt;count&lt;/code&gt;, the data list and a &lt;code&gt;billing&lt;/code&gt; object that shows what the call cost and your remaining balance:&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;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tickers"&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="nl"&gt;"symbol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"last_price"&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.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;"bid"&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.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;"ask"&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.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;"observed_epoch"&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="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"billing"&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="nl"&gt;"request_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"charged_eur"&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.002&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"balance_eur"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;19.998&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;You can check that the service is up for free, without a key:&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="nt"&gt;-s&lt;/span&gt; https://api.waveleta.com/v1/health
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Python
&lt;/h2&gt;

&lt;p&gt;No SDK needed. This uses &lt;code&gt;requests&lt;/code&gt; (&lt;code&gt;pip install requests&lt;/code&gt;):&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;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&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;https://api.waveleta.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;session&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="nc"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&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="o"&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;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;WAVELETA_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;):&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;session&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="si"&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;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&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;30&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;402&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Waveleta balance too low: top up at waveleta.com/developer/join&lt;/span&gt;&lt;span class="sh"&gt;"&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;429&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&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 limited: wait a few seconds and retry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&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;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&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="c1"&gt;# 1) Crypto prices (600+ markets, refreshed every minute)
&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/v1/crypto/tickers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&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;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tickers&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;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbol&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;t&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;last_price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# 2) FX daily reference rates (refreshed each business day)
&lt;/span&gt;&lt;span class="n"&gt;fx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/v1/fx/rates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&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;rate&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;fx&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="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;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;rate&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pair&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;rate&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="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;rate&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;as_of_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# 3) Commodities: WTI, Brent and natural gas (weekly)
&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/v1/commodities&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="n"&gt;com&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;commodities&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;print&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;instrument_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;c&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;observed_at&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Balance left:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;billing&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;balance_eur&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;EUR&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;Each &lt;code&gt;get()&lt;/code&gt; call above is one billable call, so this script costs €0.006.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript (Node 18+)
&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;BASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.waveleta.com&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;KEY&lt;/span&gt; &lt;span class="o"&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;WAVELETA_API_KEY&lt;/span&gt;&lt;span class="p"&gt;;&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&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;url&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;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BASE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;v&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;res&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="nx"&gt;url&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;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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;402&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Waveleta balance too low: top up first&lt;/span&gt;&lt;span class="dl"&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rate limited: retry in a few seconds&lt;/span&gt;&lt;span class="dl"&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Waveleta API error &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&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="k"&gt;return&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;crypto&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/v1/crypto/tickers&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;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tickers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last_price&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;fx&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/v1/fx/rates&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;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;fx&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="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;pair&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="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;as_of_date&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Balance left:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;billing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;balance_eur&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it as an ES module (&lt;code&gt;node quickstart.mjs&lt;/code&gt;). &lt;strong&gt;Never call the API directly from front-end code&lt;/strong&gt;: your key would be visible to anyone who opens the browser's developer tools. Call it from your server, a serverless function or a build step, and serve the result to your page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Look up a single market
&lt;/h2&gt;

&lt;p&gt;Pass &lt;code&gt;symbol&lt;/code&gt; to the tickers endpoint to get one market instead of a list. Use the symbol exactly as it appears in the tickers list:&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="n"&gt;btc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/v1/crypto/tickers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;symbol from the list&amp;gt;&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;For US equities history (early access), &lt;code&gt;symbol&lt;/code&gt; is required:&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="n"&gt;bars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/v1/equities/history&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Keep your bill small: cache
&lt;/h2&gt;

&lt;p&gt;At €0.002 a call, cost is about how often you call, not how much data you get back. A few habits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cache responses.&lt;/strong&gt; Crypto prices refresh every minute, so there's no point calling more often than that. FX reference rates change once per business day, and commodities once a week, so cache those for hours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;limit&lt;/code&gt;.&lt;/strong&gt; Ask for the rows you need in one call instead of one call per market.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle 402 and 429.&lt;/strong&gt; Back off on 429 and alert yourself on 402, so a script doesn't loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example: refreshing a 50-market crypto table once a minute, 24/7, is 43,200 calls a month, about €86. Refreshing it every 10 minutes is about €8.60.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate a client from the OpenAPI spec
&lt;/h2&gt;

&lt;p&gt;The spec is public at &lt;code&gt;https://api.waveleta.com/openapi.json&lt;/code&gt; (OpenAPI 3.1). Feed it to your favourite generator, or import it into Postman or Insomnia to try requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not a coder? Use WordPress
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Waveleta&lt;/strong&gt; WordPress plugin wraps all of this in shortcodes, blocks and Elementor widgets. See the &lt;a href="https://waveleta.com/developer/wordpress" rel="noopener noreferrer"&gt;Waveleta WordPress guide&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Is there an official Waveleta SDK?&lt;/strong&gt;&lt;br&gt;
You don't need one. The API is plain JSON over HTTPS, and the OpenAPI spec lets you generate a client in most languages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which header should I use, Bearer or X-Api-Key?&lt;/strong&gt;&lt;br&gt;
Either works. Pick one and use it consistently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does a failed request cost money?&lt;/strong&gt;&lt;br&gt;
Requests rejected for an invalid key (401) or a low balance (402) aren't billed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I call the API from the browser?&lt;/strong&gt;&lt;br&gt;
Technically yes, but don't: it exposes your key. Call it server-side.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://waveleta.com/developer/join" rel="noopener noreferrer"&gt;Create your Waveleta API key →&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Informational only, not financial advice. Waveleta is not a broker.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>javascript</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Waveleta Developer API: prepaid crypto and market data from €0.002 per call</title>
      <dc:creator>Waveleta</dc:creator>
      <pubDate>Tue, 06 Oct 2026 12:17:33 +0000</pubDate>
      <link>https://dev.to/waveleta/waveleta-developer-api-prepaid-crypto-and-market-data-from-eu0002-per-call-50ib</link>
      <guid>https://dev.to/waveleta/waveleta-developer-api-prepaid-crypto-and-market-data-from-eu0002-per-call-50ib</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://waveleta.com/blog/waveleta-developer-api" rel="noopener noreferrer"&gt;waveleta.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Waveleta Developer API&lt;/strong&gt; opens up the market data behind the Waveleta app to developers. It's prepaid and pay-per-call: you top up at least €20, each call costs €0.002, and there's no monthly plan. That's about 10,000 calls for €20. Here's what's in it, how billing works and how to get a key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built a prepaid API
&lt;/h2&gt;

&lt;p&gt;When I started building &lt;a href="https://waveleta.com/blog/what-is-waveleta" rel="noopener noreferrer"&gt;Waveleta&lt;/a&gt;, I kept running into the same problem with data for side projects: the useful APIs want a monthly subscription before you've written a line of code. For a hobby dashboard or a small WordPress site that makes a few thousand calls a month, that's backwards.&lt;/p&gt;

&lt;p&gt;So the Waveleta API works like a prepaid phone card. You put money on it, every call takes a small amount off, and when the balance runs out, calls stop. You never get a surprise bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  What data the Waveleta API covers
&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;What you get&lt;/th&gt;
&lt;th&gt;Update rhythm&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/crypto/tickers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Last price, bid and ask for 600+ crypto markets, filterable by &lt;code&gt;symbol&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Refreshed every minute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/fx/rates&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FX daily reference rates&lt;/td&gt;
&lt;td&gt;Refreshed each business day (end-of-day, not intraday)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/equities/history&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;US equities price history by &lt;code&gt;symbol&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Early access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/commodities&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;WTI, Brent and natural gas&lt;/td&gt;
&lt;td&gt;Updated weekly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/radar/candidates&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Markets where activity is currently changing, ranked the same way as in the Waveleta app&lt;/td&gt;
&lt;td&gt;Follows the app's ranking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/crypto/meta&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Crypto metadata where available&lt;/td&gt;
&lt;td&gt;Varies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/meta/sources&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Source and attribution details for each dataset&lt;/td&gt;
&lt;td&gt;–&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GET /v1/health&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Service status (free, no billing)&lt;/td&gt;
&lt;td&gt;–&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Responses are plain JSON. The full OpenAPI 3.1 spec is published at &lt;code&gt;https://api.waveleta.com/openapi.json&lt;/code&gt;, so you can generate a client in most languages.&lt;/p&gt;

&lt;p&gt;A note on FX: these are daily reference rates, published once per business day. They're ideal for converters, accounting, reporting and "rate of the day" widgets, and not meant for intraday use. I wrote more about that in &lt;a href="https://waveleta.com/blog/fx-reference-rates-vs-intraday" rel="noopener noreferrer"&gt;FX reference rates vs intraday quotes&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How pricing works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;€0.002 per billable call&lt;/strong&gt;, deducted from a prepaid balance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;€20 minimum top-up&lt;/strong&gt; before your first API key is issued.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No subscription&lt;/strong&gt;, no tiers, no sales call.&lt;/li&gt;
&lt;li&gt;When your balance reaches zero, the API returns HTTP &lt;code&gt;402&lt;/code&gt; and stops charging. Top up and carry on.&lt;/li&gt;
&lt;li&gt;Every billable response includes a small &lt;code&gt;billing&lt;/code&gt; object with what the call cost and your remaining balance, so you always know where you stand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API account is separate from a Waveleta app subscription. You don't need the €39/month app to use the API, and the API doesn't include the app.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get a Waveleta API key
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://waveleta.com/developer/join" rel="noopener noreferrer"&gt;waveleta.com/developer/join&lt;/a&gt; and create a developer account with your email.&lt;/li&gt;
&lt;li&gt;Pass the bot check and confirm your email address.&lt;/li&gt;
&lt;li&gt;Top up at least €20.&lt;/li&gt;
&lt;li&gt;Create an API key. Keys start with &lt;code&gt;wl_&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then send it with each request, either as a Bearer token or as an &lt;code&gt;X-Api-Key&lt;/code&gt; header:&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="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer wl_your_key_here"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://api.waveleta.com/v1/crypto/tickers?limit=5"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For full Python and JavaScript examples, see &lt;a href="https://waveleta.com/blog/waveleta-api-python-javascript" rel="noopener noreferrer"&gt;Getting started with the Waveleta API in Python and JavaScript&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error codes you'll see
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Status&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;401&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Missing or invalid API key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;402&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Balance too low, top up to continue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;422&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A parameter is missing or invalid (for example &lt;code&gt;symbol&lt;/code&gt; on equities history)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;429&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Too many requests per minute for this key, slow down and retry&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Using it on WordPress
&lt;/h2&gt;

&lt;p&gt;If you run a WordPress site, you don't need to write code at all. The &lt;strong&gt;Waveleta&lt;/strong&gt; WordPress plugin uses the same API key to show crypto prices, FX rates, a ticker, charts and more through shortcodes, Gutenberg blocks and Elementor widgets. See the &lt;a href="https://waveleta.com/developer/wordpress" rel="noopener noreferrer"&gt;Waveleta WordPress guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Good fits for the Waveleta API
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Personal dashboards and side projects that need crypto prices without a monthly plan&lt;/li&gt;
&lt;li&gt;Currency converters and "rate of the day" widgets based on daily reference rates&lt;/li&gt;
&lt;li&gt;Newsletters and reports that pull a weekly oil and gas snapshot&lt;/li&gt;
&lt;li&gt;Blogs and community sites that want a small crypto price table or ticker&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;How much does the Waveleta API cost?&lt;/strong&gt;&lt;br&gt;
€0.002 per call from a prepaid balance. The minimum top-up is €20, which is about 10,000 calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there a monthly fee?&lt;/strong&gt;&lt;br&gt;
No. You only pay for the calls you make.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens when my balance runs out?&lt;/strong&gt;&lt;br&gt;
Calls return HTTP 402 and nothing more is charged until you top up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need a Waveleta app subscription?&lt;/strong&gt;&lt;br&gt;
No. Developer accounts are separate from the app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the FX data intraday?&lt;/strong&gt;&lt;br&gt;
No. FX data is daily reference rates, refreshed each business day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where do I sign up?&lt;/strong&gt;&lt;br&gt;
At &lt;a href="https://waveleta.com/developer/join" rel="noopener noreferrer"&gt;waveleta.com/developer/join&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Informational only, not financial advice. Waveleta is not a broker.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>crypto</category>
      <category>saas</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
