Transactions → Google Sheets overview

Import affiliate transactions, commissions, and statuses into Google Sheets using Apps Script. The sample defaults to the last 30 days, paginates safely, and flattens JSON:API transaction payloads into a Transactions tab.

Endpoint: GET /api/v1/transactions

List responses wrap JSON:API under transactions. Use start_date and end_date for analytics windows; status accepts values such as pending, approved, paid, or corrected.

Setup in Google Sheets

  1. Open a Google Sheet → ExtensionsApps Script.
  2. Get your personal API key from API key docs. Prefer the X-Api-Key header (these samples already do).
  3. In Apps Script, open Project SettingsScript properties and add HIENERGY_API_KEY with your key value.
  4. Paste the shared client library, then the resource import script below.
  5. Click Save, reload the Sheet, and run the import from the Hi Energy AI menu (or Run in the editor).
  6. On first run, authorize the script when Google prompts for UrlFetchApp / external request permission.

1. Shared Apps Script client

Paste this helper library into your Apps Script project once. Every Hi Energy Google Sheets importer on this site reuses the same UrlFetchApp client, JSON:API flattener, and sheet writer.

/**
 * Hi Energy AI — shared Google Apps Script client
 * Paste this into Extensions → Apps Script, then add a resource script below.
 *
 * Setup:
 * 1. File → Project properties → Script properties
 * 2. Add property HIENERGY_API_KEY = your personal API key
 *    (from https://app.hienergy.ai/api_documentation/api_key)
 * 3. Optionally override HIENERGY_API_BASE if you use a custom host
 */

var HIENERGY_API_BASE = 'https://app.hienergy.ai';

function getHiEnergyApiKey_() {
  var key = PropertiesService.getScriptProperties().getProperty('HIENERGY_API_KEY');
  if (!key) {
    throw new Error(
      'Missing Script Property HIENERGY_API_KEY. ' +
      'Open Project Settings → Script properties and add your API key.'
    );
  }
  return key;
}

function hiEnergyApiGet_(path, query) {
  var url = HIENERGY_API_BASE + path;
  var params = [];
  Object.keys(query || {}).forEach(function(key) {
    var value = query[key];
    if (value === null || value === undefined || value === '') return;
    params.push(encodeURIComponent(key) + '=' + encodeURIComponent(String(value)));
  });
  if (params.length) url += '?' + params.join('&');

  var response = UrlFetchApp.fetch(url, {
    method: 'get',
    headers: {
      'X-Api-Key': getHiEnergyApiKey_(),
      'Accept': 'application/json'
    },
    muteHttpExceptions: true,
    followRedirects: true
  });

  var code = response.getResponseCode();
  var body = response.getContentText();
  var json = null;
  try { json = JSON.parse(body); } catch (e) {}

  if (code < 200 || code >= 300) {
    var message = (json && (json.error || json.message)) || body;
    throw new Error('Hi Energy AI API HTTP ' + code + ': ' + message);
  }
  return json;
}

function flattenJsonApiItem_(item) {
  var row = {};
  if (!item || typeof item !== 'object') return row;
  if (item.id !== undefined) row.id = item.id;
  if (item.type !== undefined) row.type = item.type;
  var attrs = item.attributes || {};
  Object.keys(attrs).forEach(function(key) {
    var value = attrs[key];
    row[key] = (value !== null && typeof value === 'object') ? JSON.stringify(value) : value;
  });
  return row;
}

function extractJsonApiCollection_(payload, preferredKeys) {
  if (!payload) return [];
  var keys = preferredKeys || ['data'];
  for (var i = 0; i < keys.length; i++) {
    var key = keys[i];
    var node = payload[key];
    if (Array.isArray(node)) return node;
    if (node && Array.isArray(node.data)) return node.data;
  }
  if (Array.isArray(payload.data)) return payload.data;
  return [];
}

function uniqueHeaders_(rows) {
  var seen = {};
  var headers = [];
  rows.forEach(function(row) {
    Object.keys(row).forEach(function(key) {
      if (!seen[key]) {
        seen[key] = true;
        headers.push(key);
      }
    });
  });
  return headers;
}

function writeObjectsToSheet_(sheetName, rows, clearSheet) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName(sheetName) || ss.insertSheet(sheetName);
  if (clearSheet !== false) sheet.clearContents();

  if (!rows.length) {
    sheet.getRange(1, 1).setValue('No rows returned');
    return 0;
  }

  var headers = uniqueHeaders_(rows);
  var values = [headers].concat(rows.map(function(row) {
    return headers.map(function(header) {
      var value = row[header];
      return value === undefined || value === null ? '' : value;
    });
  }));

  sheet.getRange(1, 1, values.length, headers.length).setValues(values);
  sheet.setFrozenRows(1);
  return rows.length;
}

function isoDateDaysAgo_(days) {
  var date = new Date();
  date.setDate(date.getDate() - days);
  return Utilities.formatDate(date, Session.getScriptTimeZone(), 'yyyy-MM-dd');
}

function isoDateToday_() {
  return Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyy-MM-dd');
}

2. Transactions import script

Paste this below the shared client, save the project, then run the import function (or use the Hi Energy AI custom menu after reloading the sheet).

/**
 * Import affiliate transactions into Google Sheets.
 * Requires the shared Hi Energy client helpers in this Apps Script project.
 *
 * Defaults to the last 30 days. Adjust START_DATE / END_DATE / STATUS as needed.
 */
function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('Hi Energy AI')
    .addItem('Import transactions', 'importHiEnergyTransactions')
    .addToUi();
}

function importHiEnergyTransactions() {
  var START_DATE = isoDateDaysAgo_(30);
  var END_DATE = isoDateToday_();
  var STATUS = ''; // e.g. 'approved', 'pending', 'paid', 'corrected'

  var page = 1;
  var perPage = 100;
  var allRows = [];
  var maxPages = 50;

  while (page <= maxPages) {
    var payload = hiEnergyApiGet_('/api/v1/transactions', {
      start_date: START_DATE,
      end_date: END_DATE,
      status: STATUS,
      page: page,
      per_page: perPage,
      include_total: false
    });

    var records = extractJsonApiCollection_(payload, ['transactions', 'data']);
    if (!records.length) break;

    records.forEach(function(item) {
      allRows.push(flattenJsonApiItem_(item));
    });

    if (records.length < perPage) break;
    page += 1;
  }

  var count = writeObjectsToSheet_('Transactions', allRows, true);
  SpreadsheetApp.getActiveSpreadsheet().toast('Imported ' + count + ' transactions', 'Hi Energy AI', 5);
}

Useful query parameters

Parameter Purpose
start_date / end_date Inclusive transaction date bounds (YYYY-MM-DD).
status pending, approved, paid, corrected (and multi-status where supported).
advertiser_id / advertiser_slug Limit to one program.
network_id / network_slug Filter by affiliate network.
currency ISO currency code such as USD.
sort_by / sort_order Order results for reporting workflows.
page / per_page Offset pagination used by the importer loop.

FAQ

Use the paste-ready Apps Script on this page to call GET /api/v1/transactions with X-Api-Key, paginate results, and write rows to a Transactions sheet.

Start with the last 30 days sample. Narrow or widen START_DATE and END_DATE for finance closes, publisher reports, or reconciliations.

Transactions search depends on Searchkick/Elasticsearch availability and your publisher scope. Check the Transactions API docs and API status page if requests fail.

Yes. Set STATUS to pending, approved, paid, or corrected, and optionally filter by advertiser_id, network_id / network_slug, currency, and sort_by / sort_order before running the importer.

Yes. Flattened JSON:API attributes typically include commission, sale amount, currency, status, and related advertiser or network fields your account can see.

Yes. This page publishes TechArticle, HowTo, FAQPage, BreadcrumbList, WebSite SearchAction, and related endpoint ItemList structured data for answer engines.
Ask Dex AIIntegration help

If this page feels TLDR, ask Dex AI.

Dex AI speaks your language, and all the other languages you may not. It will write the integration for you with the right endpoint and headers in one plain-English answer.