In 2017, Yahoo rolled out its API for Yahoo Finance, but over time it was discovered that the frontend API of the Yahoo services themselves could be used as an alternative.

I’ve built a small class based on Google Apps Script that can be used as a component in other projects. There is a library version on my Github — https://github.com/pamnard/YahooFinanceApp, but I don’t like how the libraries work in GAS, so I rewrote everything to an embedded class.

class YahooFinanceApp {
  constructor() {
    this.connect = function api(symbol, module) {
      const baseUrl = 'https://query2.finance.yahoo.com/v10/finance/quoteSummary/',
        options = {
          'muteHttpExceptions': true,
          'headers': get_headers(),
          'method': 'GET',
          'contentType': 'application/json; charset=utf-8',
        },
        fullUrl = `${baseUrl}${symbol}?modules=${module}`;
      var json;
      while (json == undefined) {
        Utilities.sleep(500); //Avoids HTTP 429 (Too many requests)
        var response = UrlFetchApp.fetch(fullUrl, options);
        var json = JSON.parse(response);
      }
      if (!!json.quoteSummary) {
        if (json.quoteSummary.error != null) {
          return json.quoteSummary
        } else {
          return json.quoteSummary.result[0]
        }

      } else {
        throw new Error('Connection blocked');
      }
      function get_headers() {
        return {
          'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
          'accept-encoding': 'gzip, deflate, br',
          'accept-language': 'en-GB,en;q=0.9,en-US;q=0.8,ml;q=0.7',
          'cache-control': 'max-age=0',
          'dnt': '1',
          'sec-fetch-dest': 'document',
          'sec-fetch-mode': 'navigate',
          'sec-fetch-site': 'none',
          'sec-fetch-user': '?1',
          'upgrade-insecure-requests': '1',
          'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36'
        }
      }
    }
  }
  assetProfile(symbol) {
    return this.connect(symbol, 'assetProfile');
  }
  incomeStatementHistory(symbol) {
    return this.connect(symbol, 'incomeStatementHistory');
  }
  incomeStatementHistoryQuarterly(symbol) {
    return this.connect(symbol, 'incomeStatementHistoryQuarterly');
  }
  balanceSheetHistory(symbol) {
    return this.connect(symbol, 'balanceSheetHistory');
  }
  balanceSheetHistoryQuarterly(symbol) {
    return this.connect(symbol, 'balanceSheetHistoryQuarterly');
  }
  cashflowStatementHistory(symbol) {
    return this.connect(symbol, 'cashflowStatementHistory');
  }
  cashflowStatementHistoryQuarterly(symbol) {
    return this.connect(symbol, 'cashflowStatementHistoryQuarterly');
  }
  defaultKeyStatistics(symbol) {
    return this.connect(symbol, 'defaultKeyStatistics');
  }
  financialData(symbol) {
    return this.connect(symbol, 'financialData');
  }
  calendarEvents(symbol) {
    return this.connect(symbol, 'calendarEvents');
  }
  secFilings(symbol) {
    return this.connect(symbol, 'secFilings');
  }
  recommendationTrend(symbol) {
    return this.connect(symbol, 'recommendationTrend');
  }
  upgradeDowngradeHistory(symbol) {
    return this.connect(symbol, 'upgradeDowngradeHistory');
  }
  institutionOwnership(symbol) {
    return this.connect(symbol, 'institutionOwnership');
  }
  fundOwnership(symbol) {
    return this.connect(symbol, 'fundOwnership');
  }
  majorDirectHolders(symbol) {
    return this.connect(symbol, 'majorDirectHolders');
  }
  majorHoldersBreakdown(symbol) {
    return this.connect(symbol, 'majorHoldersBreakdown');
  }
  insiderTransactions(symbol) {
    return this.connect(symbol, 'insiderTransactions');
  }
  insiderHolders(symbol) {
    return this.connect(symbol, 'insiderHolders');
  }
  netSharePurchaseActivity(symbol) {
    return this.connect(symbol, 'netSharePurchaseActivity');
  }
  earnings(symbol) {
    return this.connect(symbol, 'earnings');
  }
  earningsHistory(symbol) {
    return this.connect(symbol, 'earningsHistory');
  }
  earningsTrend(symbol) {
    return this.connect(symbol, 'earningsTrend');
  }
  industryTrend(symbol) {
    return this.connect(symbol, 'industryTrend');
  }
  indexTrend(symbol) {
    return this.connect(symbol, 'indexTrend');
  }
  sectorTrend(symbol) {
    return this.connect(symbol, 'sectorTrend');
  }
};

Add the class to a separate project file, and call it from anywhere. For example, a request like this will return data on AAPL (Apple):

var json = new YahooFinanceApp().financialData('AAPL');

It’s as if you clicked on a link in the browser https://query2.finance.yahoo.com/v10/finance/quoteSummary/AAPL?modules=financialData

All methods of the class are similar to modules of the API itself. If you have already used it before, everything will be intuitive.