Search code examples
rjsonrestgettiingo

Connect to Rest API in R with key


this is a simple question, but one that I still can't figure out. I want to connect to a REST API with my API key. I've looked through the documentation on httr, jsonlite and others and still can't figure out how to set the API key.

This is the endpoint - https://api.tiingo.com/tiingo/daily//prices?startDate=2012-1-1&endDate=2016-1-1?

I've tried using the GET function on this URL and specify my API key as key in the call. I've also tried api_key = key. I always get a 401 error back.

Thanks


Solution

  • The API is expecting a Authorization header with Token yOuRAsSiGnEdT0k3n in it. You should store the token in something like an environment variable so it's not stuck in scripts. I used TIINGO_TOKEN and put it into ~/.Renviron.

    You can make a helper function to make the calls less mudane:

    library(httr)
    library(jsonlite)
    library(tidyverse)
    library(hrbrthemes)
    
    get_prices <- function(ticker, start_date, end_date, token=Sys.getenv("TIINGO_TOKEN")) {
    
      GET(
        url = sprintf("https://api.tiingo.com/tiingo/daily/%s/prices", ticker),
        query = list(
          startDate = start_date,
          endDate = end_date
        ),
        content_type_json(),
        add_headers(`Authorization` = sprintf("Token %s", token))
      ) -> res
    
      stop_for_status(res)
    
      content(res, as="text", encoding="UTF-8") %>%
        fromJSON(flatten=TRUE) %>%
        as_tibble() %>%
        readr::type_convert()
    
    }
    

    Now, you can just pass in parameters:

    xdf <- get_prices("googl", "2012-1-1", "2016-1-1")
    
    glimpse(xdf)
    ## Observations: 1,006
    ## Variables: 13
    ## $ date        <dttm> 2012-01-03, 2012-01-04, 2012-01-05, 2012-01-06, 2...
    ## $ close       <dbl> 665.41, 668.28, 659.01, 650.02, 622.46, 623.14, 62...
    ## $ high        <dbl> 668.15, 670.25, 663.97, 660.00, 647.00, 633.80, 62...
    ## $ low         <dbl> 652.3700, 660.6200, 656.2300, 649.7900, 621.2300, ...
    ## $ open        <dbl> 652.94, 665.03, 662.13, 659.15, 646.50, 629.75, 62...
    ## $ volume      <int> 7345600, 5722200, 6559200, 5380400, 11633500, 8782...
    ## $ adjClose    <dbl> 333.7352, 335.1747, 330.5253, 326.0164, 312.1937, ...
    ## $ adjHigh     <dbl> 335.1095, 336.1627, 333.0130, 331.0218, 324.5017, ...
    ## $ adjLow      <dbl> 327.1950, 331.3328, 329.1310, 325.9010, 311.5768, ...
    ## $ adjOpen     <dbl> 327.4809, 333.5446, 332.0901, 330.5955, 324.2509, ...
    ## $ adjVolume   <int> 3676476, 2863963, 3282882, 2692892, 5822572, 43955...
    ## $ divCash     <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
    ## $ splitFactor <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,...
    

    And, it "just works":

    ggplot(xdf, aes(date, close)) +
      geom_segment(aes(xend=date, yend=0), size=0.25) +
      scale_y_comma() +
      theme_ipsum_rc(grid="Y")
    

    enter image description here

    You can follow this idiom for the other API endpoints. When done, consider making a package out of it so the community can use what the knowledge you gained.

    You can go some extra steps and actually make functions that take date or numeric parameters to actually take those type of R objects and validate them on input, too.