> For the complete documentation index, see [llms.txt](https://docs.relevant-digital.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.relevant-digital.com/api/api-reference/how-to-export-reporting-data-through-hb-analytics-pull-api.md).

# How to Export Reporting data through HB Analytics Pull API

## This short guide will help you build the API call, and explain the basics for collecting reporting data from HB Analytics.

The Pull API in HB Analytics enables users to export their data to external systems or for various other purposes.

### Preparations:

We recommend going through these steps before creating API requests:

1. You can either use an existing Admin User in the system or you can create a new Admin User to be utilised as a dedicated API user. We recommend creating a new Admin User. This means that you can avoid having to make changes to your API requests, if you would need to delete the user whose account has been used in the requests.
2. Create the new Admin user in [Administrators](/general-platform/user-management/administrator-admin-users.md), if you decide to follow our recommendation to use a separate Admin user for the API requests.
3. Make sure you have the right URL. All clients have their own unique Domain URL. Please ask your Technical Account Manager for the correct domain to call.

### The script example:

This example showcases the functions with some explanations. Please see further sections of this article for more details:

```javascript
// WARNING: including all available dimensions like below will most likely *not* work with live-data
// with millions of ad-requests (an error will be returned).
const runReport = async (startTs, endTs) => {
  const HOST = 'YOUR_URL_ASK_YOUR_TECHNICAL_ACCOUNT_MANAGER'; // Change to real host!
  const CREDENTIALS = {
    email: 'user@example.com', // Change to real user-name (email)
    password: 'mypassword', // Change to real user's password
  };
  let token; // Our auth-token, to be obtained below

  // Fetch data from API, response will be an object with the result in .result
  const fetchData = (path, body) => fetch(`${HOST}${path}`, {
    headers: {
      "accept": "*/*",
      "content-type": "application/json",
      "authorization": token,
    },
    body: JSON.stringify(body),
    method: 'POST',
    mode: 'cors',
  }).then(r => r.json()).then((d) => d.result);

  // Step 1: Fetch an authentication token
  ({ token } = await fetchData('/users/login', CREDENTIALS));

  const groupBy = [
    'date', // Timeperiod
    'publisherId', // Publisher
    'siteId', // Site
    'bidder', // Bidder
    'sourceId', // Source
    'placementId', // Placement
    'bidRange', // Bid range
    'size', // Creative Size
    'mediaType', // Media Type
    '__sys_Prebid Configuration', // Prebid Configuration
    '__sys_Browser name', // Browser name
    '__sys_Browser version', // Browser version
    '__sys_Hostname', // Hostname
    '__sys_Operating system', // Operating system
    '__sys_Platform', // Platform
    '__sys_URL', // URL
  ];

  const sums = [
    'revenue', // Revenue
    'pageViews', // Auctions (Notice: *auctions* and not "page-views")
    'adserverIn', // Ad unit requests
    'renderSuccess', // Impressions
    'bidWon', // Winning bids
    'bids', // Bid requests
    'bidVolume', // Total bid revenue
    'unloadBeforeResponse', // Cancelled bids
    'timedOut', // Timed out bids
    'noBid', // No bid responses
    'bidResponse', // Bid responses
    'renderFailed', // Failed renderings
    'responseMs', // Total response milliseconds, Avg. response ms = responseMs / (bidResponse + noBid)
    'renderMs', // Total render milliseconds, Avg. render ms = renderMs / bidWon
  ];

  // Step 2: Run the report. The result will be an array with metrics and dimensions.
  // For each dimension there will be two fields:
  // - [dim-name] - Relevant Yield internal id
  // - [dim-name]_label - Human friendly name
  // Exception: for date there will not be any date_label. Instead it will just be date which is the milliseconds
  // since 1970-01-01 (UTC), similar to: new Date().getTime()
  return fetchData('/reports', {
    customCommand: 'reportHb',
    reportFormat: 'array', // Result will be a JSON-array (default is a nested object)
    startTs, // Start millisecond for report
    endTs, // End millisecond for report, 0 means "until now"
    groupBy, // Dimensions
    sums, // Metrics
    timeRangeMs: 600 * 1000, // Group data per 10 minutes (600 seconds)
    splitByAuctionRunner: false, // Set to true to split bidders by calls done Client-/Server-side on Web
  });
};

// Run report between midnight (UTC) and now + log result
const runReportForToday = async () => {
  const reportArray = await runReport(new Date().setUTCHours(0,0,0,0), new Date().getTime());
  console.info('The result:', reportArray);
};
```

{% stepper %}
{% step %}

## 1. Setting up the Credentials and the Domain you need to access:

```javascript
const runReport = async (startTs, endTs) => {
  const HOST = 'YOUR_URL_ASK_YOUR_TECHNICAL_ACCOUNT_MANAGER'; // Change to real host!
  const CREDENTIALS = {
    email: 'user@example.com', // Change to real user-name (email)
    password: 'mypassword', // Change to real user's password
  };
```

{% endstep %}

{% step %}

## 2. Options on how to group your output:

```javascript
const groupBy = [
  'date', // Timeperiod
  'publisherId', // Publisher
  'siteId', // Site
  'bidder', // Bidder
  'sourceId', // Source
  'placementId', // Placement
  'bidRange', // Bid range
  'size', // Creative Size
  'mediaType', // Media Type
  '__sys_Prebid Configuration', // Prebid Configuration
  '__sys_Browser name', // Browser name
  '__sys_Browser version', // Browser version
  '__sys_Hostname', // Hostname
  '__sys_Operating system', // Operating system
  '__sys_Platform', // Platform
  '__sys_URL', // URL
];
```

{% endstep %}

{% step %}

## 3. Selecting the Metrics you would like to report on:

```javascript
const sums = [
  'revenue', // Revenue
  'pageViews', // Auctions (Notice: *auctions* and not "page-views")
  'adserverIn', // Ad unit requests
  'renderSuccess', // Impressions
  'bidWon', // Winning bids
  'bids', // Bid requests
  'bidVolume', // Total bid revenue
  'unloadBeforeResponse', // Cancelled bids
  'timedOut', // Timed out bids
  'noBid', // No bid responses
  'isApproximation', // Is approximation
  'bidResponse', // Bid responses
  'renderFailed', // Failed renderings
  'uniqueBidRevenue', // Unique HB bid revenue
  'incrementalBidRevenue', // Incremental HB bid revenue
  'lostToAdserverRevenue', // Lost revenue to adserver
  'isAdserverBid', // Adserver bids
  'responseMs', // Total response milliseconds, Avg. response ms = responseMs / (bidResponse + noBid)
  'renderMs', // Total render milliseconds, Avg. render ms = renderMs / bidWon
];
```

{% endstep %}

{% step %}

## 4. Running the report:

```javascript
// Step 2: Run the report. The result will be an array with metrics and dimensions.
// For each dimension there will be two fields:
// - [dim-name] - Relevant Yield internal id
// - [dim-name]_label - Human friendly name
// Exception: for date there will not be any date_label. Instead it will just be date which is the milliseconds
// since 1970-01-01 (UTC), similar to: new Date().getTime()
return fetchData('/reports', {
  customCommand: 'reportHb',
  reportFormat: 'array', // Result will be a JSON-array (default is a nested object)
  startTs, // Start millisecond for report
  endTs, // End millisecond for report, 0 means "until now"
  groupBy, // Dimensions
  sums, // Metrics
  timeRangeMs: 600 * 1000, // Group data per 10 minutes (600 seconds)
  splitByAuctionRunner: false, // Set to true to split bidders by calls done Client-/Server-side on Web
});

// Run report between midnight (UTC) and now + log result
const runReportForToday = async () => {
  const reportArray = await runReport(new Date().setUTCHours(0,0,0,0), new Date().getTime());
  console.info('The result:', reportArray);
```

{% endstep %}
{% endstepper %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.relevant-digital.com/api/api-reference/how-to-export-reporting-data-through-hb-analytics-pull-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
