Skip to main content

Get Reporting Data via API


This short tutorial shows you how to use the Holistics APIs to get report data in raw tabular form (CSV, Excel).

This tutorial uses Ruby, but you can easily use any other language for it. You can also refer to the full source code here.


We'll be working on client libraries wrapper around our API. Once done, using the APIs will be simpler by just making a few function calls.


Since Holistics uses a async job queuing system to process job, you can't make a single API call to retrieve the results. We need to submit an 'export request', then wait for the export job to finish, and then make an API call to download the results.

API Endpoints used:


Let's go through the steps here.

1. Setting Up API Key

Please see guide to set up and retrieve your API key.

2. Initial code structure

To make things simple and reusable, we'll wrap our code around a HolisticsAPI class. We'll also use the httprb gem to handle making HTTP calls.

require 'http'
class HolisticsAPI
def initialize(api_key, host: '')
@api_key = api_key
@api_url = "https://#{host}/api/v2"
@http = HTTP.headers({'X-Holistics-Key' => @api_key})

3. Submit widget export request

Make sure you have the DashboardWidget ID in hand. The widget ID can be retrieved by opening up the widget in the dashboard, and look at the _e parameter in the URL. For example, 4175 is the widget ID of the below.

Then we make the call to submit widget export:

class HolisticsAPI
# ...

# output: 'csv' or 'excel'
def submit_report(widget_id, output: 'csv')
url = @api_url + "/dashboard_widgets/" + widget_id.to_s + "/submit_export"

response =, json: {output: output})
res = JSON.parse(response.to_s)

if response.code == 200

If successful, this method returns the job ID of the job created.

4. Waiting for job to complete

The job will the go to the queue system waiting to be processed. This method below will continuously poll the job's metadata until it is either success, or failure.

class HolisticsAPI
# ...

def wait_for_job_status(job_id)
url = @api_url + "/jobs/" + job_id.to_s

while true do
response = @http.get(url)
res = JSON.parse(response.to_s)

raise['message']) if response.code != 200

status = res['job']['status']
puts "===> status: #{status}"

unless ['created', 'running', 'queued'].include?(status)
return status

# Wait a while before pinging again
sleep 2

5. Downloading the results

Once the job finishes, we make one final API call to

class HolisticsAPI
# ...

def download_export(job_id)
url = @api_url + "/exports/download"
response = @http.follow.get(url, params: {job_id: job_id})

raise['message'])) if response.code != 200


6. Putting things together

Once the above class is defined, let's put in a short code to perform all 3 steps to get the data.

API_KEY = 'your_api_key'
WIDGET_ID = 1234 # your widget

api =

job_id = api.submit_report(WIDGET_ID)
puts "===> job_id: #{job_id}"

job_status = api.wait_for_job_status(job_id)
puts "===> job_status: #{job_status}"

if job_status == 'success'
csv_data = api.download_export(job_id)
puts csv_data # your CSV-formatted data here!

7. Profit!

Save the data into CSV, convert them into array, or feed them to other applications. The potentials are limitless!