priceR
priceR copied to clipboard
Missing API Access Key
Looks like the API of https://exchangerate.host/ now requires an API Access Key. If you try to access
https://api./timeseries?start_date=2010-01-01&end_date=2010-12-31&base=AUD&symbols=USD
you will get the following response:
{ "success": false, "error": { "code": 101, "type": "missing_access_key", "info": "You have not supplied an API Access Key. [Required format: access_key=YOUR_ACCESS_KEY]" } }
This results in the following R error when you run historical_exchange_rates() function:
historical_exchange_rates(from = "AUD", to = "USD", start_date = "2010-01-01", end_date = "2020-06-30")
Error in
pmap()
: i In index: 1. Caused by error instack.default()
: ! at least one vector element is required Runrlang::last_error()
to see where the error occurred.
The pricing page says that it allows only 1K free requests a month. Do you think that this API can be replaced with another free one, so the priceR package can still be used?
Thanks for letting me know.
Looks like there's been a major change to the exchangerate.host API (the API priceR uses to get exchange rates). It now requires a key, which is free for 1000 requests per calendar month. (I'm making some guesses here based on the dates on the dashboard):
In the short term, I'm investigating the the extent of the damage. I hope it's possible to set the key in the R session and make everything work without any further code changes, but to see if that can be done I will first examine each endpoint (to ensure they still exist). If it's straight forward, will hopefully have changes pushed to github in a few hours.
In the long term, it would be worthwhile investigating free and unrestricted alternatives. At the time I wrote priceR's original forex functionality, it was somewhat opportunistic, since exchangerate.host was the only free and unrestricted API I knew (all other major exchange rate APIs required keys and some required payment details), so it's been great while it lasted.
I'll keep everyone updated here whatever the outcome.
Yes, I was able to follow the code all the way to here https://api.exchangerate.host/timeseries?start_date=2010-01-01&end_date=2010-12-31&base=USD&symbols=GBP and you end up with this response. { "success": false, "error": { "code": 101, "type": "missing_access_key", "info": "You have not supplied an API Access Key. [Required format: access_key=YOUR_ACCESS_KEY]" } }
Technically it's an easy fix, but it sounds like a code change will be needed no matter what :(
You can't blame them for trying to monetize here. I'm a low volume user (under 100 times a month) so would be happy to just pass that info myself!
Having said that - I tried to get an api_key but ended up with this... seems like they're working out stuff on their side:
curl "https://api.exchangerate.host/timeseries?start_date=2010-01-01&end_date=2010-12-31&base=USD&symbols=GBP&access_key=84c66myprivatekey"
{"success":false,"error":{"code":103,"type":"invalid_api_function","info":"This API Function does not exist."}}
Having read the new API documentation it looks like most of current priceR functionality will be possible with the new API, but since the endpoints, their responses and some of their parameters have changed, it will take some time to integrate these into the priceR library and ensure they produce comparable outputs to the previous API. Unfortunately it's not as simple as setting a key in the R session and inserting the key in the request URLs. Instead, priceR will need to refactored to parse the differently formatted API responses.
From a scan of the new API, it does appear some endpoints now require a paid plan to retrieve rates with a particular base currency (other than USD), if that's the case priceR should still be able to get rates for all other currencies, but may require cross rate triangulation, which will be a bit more work.
In summary unfortunately these API changes are sudden and it will take some time to work out how to get all the previous priceR functionality back using the new API and ensure it is tested and works correctly.
For now, some endpoints that may help - replace abcd1234
in the URLs below with your access key, and note the URLs use http (as opposed to https):
Live rates: http://api.exchangerate.host/live?access_key=abcd1234
Historical rates. Example from jan to may 2015. This endpoint looks powerful as it gives every currency pairing with USD, making it possible to triangulate exchange rates for all ~160 currencies for up to 365 days with a single API call (again, replace abcd1234
with your key):
http://api.exchangerate.host/timeframe?start_date=2015-01-01&end_date=2015-05-01&access_key=abcd1234
Or from R:
library(jsonlite)
fromJSON("http://api.exchangerate.host/timeframe?start_date=2015-01-01&end_date=2015-05-01&access_key=abcd1234")
There are a more endpoints to explore in the 'Available Endpoints' section of the API docs.
Sorry this isn't a more immediate fix. Hopefully we can get most/all of priceR's forex functionality back in time.
Thanks for looking into that... keep us posted as you fix this.
Having a closer look into the new exchangerate.host API, it appears there are even more changes than first thought.
For example, suppose we get the USD/AUD exchange rate for June 2010
library(jsonlite)
library(tidyverse)
df <- fromJSON("http://api.exchangerate.host/timeframe?start_date=2010-06-01&end_date=2010-06-30¤cies=AUD,USD&access_key=9f7337ae140cc2ad5704fb042125fe29")
(replace access_key=9f7337ae140cc2ad5704fb042125fe29
with yours if mine runs out)
and look at the first 6 days' data:
df[[8]] %>% head
# df[[8]] %>% head
# $`2010-06-01`
# $`2010-06-01`$USDAUD
# [1] 1.197421
#
#
# $`2010-06-02`
# $`2010-06-02`$USDAUD
# [1] 1.19466
#
#
# $`2010-06-03`
# $`2010-06-03`$USDAUD
# [1] 1.184667
#
#
# $`2010-06-04`
# $`2010-06-04`$USDAUD
# [1] 1.204761
#
#
# $`2010-06-05`
# list()
#
# $`2010-06-06`
# list()
The first 4 days' exchange rates are provided, but the last two days don't have values. Presumably it's giving data for weekdays but not weekends. Since the previous API gave daily results (including weekends), missing weekends would fundamentally change the way the historical_exchange_rates()
function works (since when using that function, one could expect weekends to be included).
Maybe exchangerate.host API will change in the future and include weekends, but my thinking for the time being is to create a few function that has NA for missing days (e.g. weekends).
Hi Steve,
Thanks for all your work! What a same, all these changes from their side. Got some processes running with PriceR that make my life a whole lot easier. About those missing weekends, isn't it an idea to take the Friday rate for weekend days for instance? But I'm a noob when it come down to this stuff... I guess I should code myself that when I receive an NA I should take the rate from the first day available.
I've written some new, experimental functionality that can be used with the new exchangerate.host API.
So far, only the historical_exchnage_rates()
function has been updated.
This code is untested, Please be on the lookout for any:
- bugs or anomalies
- possible miscalculations
- Due to way the new API works returns currency values, it's necessary to calculate rates in 3 different ways, depending on whether
- the 'from' currency is USD
- the 'to' currency is 'USD
- neither currency is USD
- Due to way the new API works returns currency values, it's necessary to calculate rates in 3 different ways, depending on whether
There is a known problem with missing date (looks like it's on weekends) for some currencies and date ranges. As far as I've seen so far it affects only data from about 10+ years ago.
To use this experimental functionality:
- install with
remotes::install_github("stevecondylios/priceR@de72f799498b905813760a30bc545082eb1d8135")
- Set your API key in the R session like so
Sys.setenv("EXCHANGERATEHOST_ACCESS_KEY"="7e5e3140140bd8e4f4650cc41fc772c0")
-
historical_exchnage_rates()
should work as before
This experimental functionality is now on CRAN, and everything should work as it did prior to changes, just requiring that a key be set in the R session first.
Install priceR from CRAN
install.packages("priceR")
library(tidyverse)
library(priceR)
# use sessionInfo() to ensure version 1.0.0 installed, if not, try this instead
# devtools::install_version("priceR", version="1.0.0", repos="https://cloud.r-project.org/")
Set API key
Make an API key here: https://exchangerate.host/
Paste it into this code and run once to set it in your R session:
Sys.setenv("EXCHANGERATEHOST_ACCESS_KEY"="your_key_goes_here")
Everything should 'just work' :tm:
Examples (same as before):
exchange_rate_latest("USD") %>%
head(10)
# currency one_USD_is_equivalent_to
# 1 AED 3.67299
# 2 AFN 77.50220
# 3 ALL 101.25030
# 4 AMD 413.44991
# 5 ANG 1.80265
# 6 AOA 829.00004
# 7 ARS 350.01992
# 8 AUD 1.58582
# 9 AWG 1.80000
# 10 AZN 1.70231
historical_exchange_rates("AUD", to = "USD",
start_date = "2013-01-01", end_date = "2023-06-30") %>% head
# date one_AUD_equivalent_to_x_USD
# 1 2013-01-01 1.037464
# 2 2013-01-02 1.049972
# 3 2013-01-03 1.047220
# 4 2013-01-04 1.048371
# 5 2013-01-05 1.048371
# 6 2013-01-06 1.049155
Well, it "just works". Thanks for your work!
Hi Steve,
Thanks for your work again. Does the historical_exchange_rates for other that USD and in combination with Time-Frame Queries in combination with the free subscription? I've rebuild everything on my and a started to log all the historical rates in a data frame, but ran into the problem I need the professional plus subscription from them.
@JasonSoesman it will work with the free subscription. Example:
library(priceR)
library(tidyverse)
historical_exchange_rates("AUD", to = "EUR",
start_date = "2022-01-01", end_date = "2023-06-30") %>% head
# date one_AUD_equivalent_to_x_EUR
# 1 2022-01-01 0.6391881
# 2 2022-01-02 0.6389321
# 3 2022-01-03 0.6368972
# 4 2022-01-04 0.6416999
# 5 2022-01-05 0.6383105
# 6 2022-01-06 0.6341034
It's able to do this by using currency cross rates (i.e. computing the rate between currencies A and B based on the USD to A and USD to B rates). The exact logic is here.
Dear @stevecondylios , I am a great fan of your package and I was using it quite a while. The big THANK YOU for creating the package. However recent changes (somewhere mid of Jan 2024) within the https://exchangerate.host/ made my life way more difficult. While they limited to 1k requests (that limit was still quite reasonable considering they wanted to monetize their service) they limited it even further. Now it has only 100 requests. Meaning if I check daily for 5 currencies I am 150% over the limit. Moreover you cannot register an account, even for that 100 requests unless you provide your credit card. So in their eyes, the pricing looks like below 100 per month with credit card is free above 100 - take 10k package... I did small research which APIs are still there and here are the free limitations:
- https://fixer.io/#pricing_plan - 100
- https://exchangeratesapi.io/#pricing_plan - 250
- https://currencyapi.com/pricing/ 300
- https://openexchangerates.org/signup/free 1000 requests per month. What do you think, would it make sense if you modify your package to use the last provider? Actually, of retrieving the historical data for quite a longer period of time with the exchangerate.host, it counts it as multiple requests.
I agree, 100 requests per month is just too small to be useful (just generating the readme for this repo takes a few dozen requests). FWIW I emailed exchangerate.host to try to change their mind but it hasn't been successful.
Thanks for researching alternatives. I think moving to openexchangerates.org is a good idea. I have used them in several projects before (via a ruby library) and it's been extremely reliable.
To do it properly, I think exchangerates.host would have to be removed and replaced entirely (i.e. across all functions that use it). I don't have the time to commit to this right now, but if someone wants to have a go and make a PR they're welcome to do so.