BI connector recipe

SEC API Looker Studio Connector

A self-serve Looker Studio Community Connector starter for analysts who want SEC filing watchlist rows inside report dashboards without building a custom EDGAR pipeline.

GET /v1/sec/watchlist/changes?tickers=AAPL,MSFT,NVDA&since=2026-07-01&limit=25
const cc = DataStudioApp.createCommunityConnector();
const HOST = "https://sec-event-intelligence.p.rapidapi.com";

function getAuthType() {
  return cc.newAuthTypeResponse()
    .setAuthType(cc.AuthType.KEY)
    .setHelpUrl("https://api.data-apis.com/quickstart")
    .build();
}

function getConfig() {
  const config = cc.getConfig();
  config
    .newTextInput()
    .setId("tickers")
    .setName("Tickers")
    .setHelpText("Comma-separated ticker symbols, for example AAPL,MSFT,NVDA.")
    .setPlaceholder("AAPL,MSFT,NVDA");
  config.setDateRangeRequired(true);
  return config.build();
}

function getSchema() {
  return {schema: getFields_().build()};
}

function getData(request) {
  const requestedFieldIds = request.fields.map(function(field) {
    return field.name;
  });
  const requestedFields = getFields_().forIds(requestedFieldIds);
  const rows = fetchRows_(request).map(function(row) {
    return {
      values: requestedFields.asArray().map(function(field) {
        return row[field.getId()];
      })
    };
  });
  return {
    schema: requestedFields.build(),
    rows: rows,
    filtersApplied: false
  };
}

function setCredentials(request) {
  const key = request.key;
  if (!key) {
    return {errorCode: "INVALID_CREDENTIALS"};
  }
  PropertiesService.getUserProperties().setProperty("RAPIDAPI_KEY", key);
  return {errorCode: "NONE"};
}

function isAuthValid() {
  return Boolean(PropertiesService.getUserProperties().getProperty("RAPIDAPI_KEY"));
}

function resetAuth() {
  PropertiesService.getUserProperties().deleteProperty("RAPIDAPI_KEY");
}

function isAdminUser() {
  return false;
}

function getFields_() {
  const fields = cc.getFields();
  const types = cc.FieldType;
  const aggregations = cc.AggregationType;
  fields.newDimension().setId("ticker").setName("Ticker").setType(types.TEXT);
  fields.newDimension().setId("form").setName("Form").setType(types.TEXT);
  fields.newDimension().setId("filed_at").setName("Filed At").setType(types.TEXT);
  fields.newDimension().setId("company_name").setName("Company").setType(types.TEXT);
  fields.newDimension().setId("accession_no").setName("Accession").setType(types.TEXT);
  fields.newDimension().setId("filing_url").setName("Filing URL").setType(types.URL);
  fields.newDimension().setId("change_type").setName("Change Type").setType(types.TEXT);
  fields.newDimension().setId("observed_at").setName("Observed At").setType(types.TEXT);
  fields
    .newMetric()
    .setId("filing_count")
    .setName("Filing Count")
    .setType(types.NUMBER)
    .setAggregation(aggregations.SUM);
  return fields;
}

function fetchRows_(request) {
  const key = PropertiesService.getUserProperties().getProperty("RAPIDAPI_KEY");
  const params = request.configParams || {};
  const tickers = params.tickers || "AAPL,MSFT,NVDA";
  const since = request.dateRange ? request.dateRange.startDate : "2026-07-01";
  const query = [
    ["tickers", tickers],
    ["since", since],
    ["limit", "25"]
  ].map(function(pair) {
    return pair[0] + "=" + encodeURIComponent(pair[1]);
  }).join("&");
  const response = UrlFetchApp.fetch(
    HOST + "/v1/sec/watchlist/changes?" + query,
    {
      headers: {
        "x-rapidapi-host": "sec-event-intelligence.p.rapidapi.com",
        "x-rapidapi-key": key
      },
      muteHttpExceptions: true
    }
  );
  if (response.getResponseCode() >= 300) {
    throw new Error(response.getContentText());
  }
  const payload = JSON.parse(response.getContentText());
  const rows = [];
  payload.data.forEach(function(group) {
    (group.changes || []).forEach(function(change) {
      const filing = change.filing || {};
      rows.push({
        ticker: group.ticker || filing.ticker || "",
        form: filing.form || "",
        filed_at: filing.filedAt || "",
        company_name: filing.companyName || "",
        accession_no: filing.accessionNo || "",
        filing_url: filing.filingUrl || "",
        change_type: change.changeType || "",
        observed_at: change.observedAt || "",
        filing_count: 1
      });
    });
  });
  return rows;
}

Workflow Setup

This recipe shows how to move SEC filing data into automation tools using live HTTPS endpoints and standard API credentials.

Endpoints Used

The integration uses live SEC Event Intelligence endpoints available through RapidAPI subscriptions.

Integration FAQ

Is this a published Looker Studio partner connector?

No. It is a starter Community Connector script for teams that want to test SEC filing reports before requesting a packaged connector.

Where is the RapidAPI key stored?

The starter uses Apps Script user properties through the connector auth flow instead of hard-coding the key in report configuration.

No investment advice. These recipes move public SEC filing metadata into automation tools. They do not provide recommendations, ratings, signals, or personalized financial guidance. The starter workflow file is available at /downloads/sec-filings-looker-studio-connector.gs.