> 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/readme.md).

# How to Export Reporting Data through Ad Revenue Insights' Pull API

If you want to collect reporting data from Ad Revenue Insights, this short guide will help you build the API call and explain the basics.

The Ad Revenue Insights module includes a Pull API, allowing you to use the collected data in other systems or simply for data exports.

## Preparations

Before you can access your data, there are a few steps to follow:

1. **User:** You can either use an existing [Admin User](/general-platform/user-management/administrator-admin-users.md) in the system or create a new Admin User to serve as a dedicated API user. We recommend creating a new Admin User specifically for the API to avoid potential issues if you need to deactivate other users. A clean, dedicated Admin user is the preferred approach.
2. **Credentials:** Obtain the credentials for the Admin User you plan to use as the API connection user.
3. **API URL:** Ensure you have the correct URL. Each client has a unique domain URL, and your account is no exception. Please contact your Technical Account Manager to confirm the correct domain to use.

## Script Example

This example highlights the functions with brief explanations, which will be covered in more detail in a later section:

```python
from datetime import datetime
import requests
import json
import os
import re
import csv
import collections
​
url = "insert_your_domain"
credentials = {"email" : 'your-email',"password" : 'your_password'}
date = '2022-04-11'
csvFileName = 'output_' + date + '.csv'
​
response = requests.post(url + "/users/login",data=credentials)
​
if response.status_code > 400:
    raise Exception('Status code: '+str(response.status_code))

token_value = response.json()["result"]["token"]
​
def runCommand(path, params):
    resp = requests.post(
        url=url + path,
        headers={
            "accept": "*/*",
            "authorization": token_value,
            "content-type": "application/json"
            },
            data=json.dumps(params)
        )
    if resp.status_code >= 400:
        raise Exception('Status code: '+str(resp.status_code))
    return resp.json()['result']
​
groupBy = [\
    'date', # Date\
    'siteId', # Site\
    'publisherId', # Publisher\
    'placementId', # Placement\
    'sourceId', # Source\
    'sspId', # SSP\
    'revenueType', # Revenue type\
    'advertiserNr', # Advertiser\
    'buyerNr', # Buyer\
    'dealNr', # Deal\
    'bidderNr', # DSP\
    'size', # Crative Size\
    'paymentTypeId', # Payment type\
    'mediaTypeId', # Media type\
    'dealTypeId', # Deal type\
    'orderNr', # Order\
    'lineItemNr', # Line item\
]
​
sums = [\
    'revenue', # API Gross revenue\
    'revenueAfterSsp', # Total revenue\
    'soldImpressions', # Sold impressions\
    'clicks', # Clicks\
    'ism',     # Viewable Imps\
    'ismMeasured', # Viewable measured\
]
​
reportSettings = {
    "customCommand": "reportProgrammatic",
    "reportFormat": "array", # new array-format..
    "start": date,
    "end": date,
    # set the below to something high to include all advertisers/buyers etc without grouping them into "[Smaller advertisers]" etc.
    "maxAdvertisers": '10000000',
    "attributes": {
        "advertiserNr": {
            "externalId": True,
        },
        "dealNr": {
            "dealId": True,
            "name": True,
        },
        "sourceId": {
            "id": True,
            "name": True,
        }
    },
    "groupBy": groupBy,
    "sums": sums,
    # uncomment the 'advMappingId'-row to not use the default advertiser mappings, that would be the same as using this report UI-setting:
    # Other options => Advertiser mapping => [Ignore default mappings]
​
    # "advMappingId": "no_mapping_magic",
}
​
result = runCommand("/reports", reportSettings)
arr = result['data']
if len(arr):
    with open(csvFileName, 'w') as file:
        wr = csv.writer(file, quoting=csv.QUOTE_ALL)
        wr.writerow(arr[0].keys())
        for row in arr:
            wr.writerow(row.values())
else:
    print("Report is empty")
​
# List import-status for all systems:
# "completed" => OK
# "failed" => Error at Import
# "none" => Import not run (yet)
ssps = runCommand("/ssps", { "customCommand": "getAll" })
tasks = runCommand("/tasks", { "customCommand": "getTasks", "start": date, "end": date, "type": "SSPimport" })
print("====== Import status by system ======")
for ssp in ssps:
    if ssp['active']: # Only include active systems
        task = next(t for t in tasks if t['objectId'] == ssp['id'])
        state = task['state'] if task else "none"
        print("\t" + ssp['name'] + ": " + state)
​
print("Done")
```

{% stepper %}
{% step %}

## Setting up the credentials, specifying the domain to access, and naming the output file:

```python
url = "INSERT_YOUR_DOMAIN"
credentials = {"email" : 'bla',"password" : 'bla'}
date = '2022-04-11'
csvFileName = 'output_' + date + '.csv'
```

{% endstep %}

{% step %}

## Options for grouping your output:

```python
groupBy = [\
    'date', # Date\
    'siteId', # Site\
    'publisherId', # Publisher\
    'placementId', # Placement\
    'sourceId', # Source\
    'sspId', # SSP\
    'revenueType', # Revenue type\
    'advertiserNr', # Advertiser\
    'buyerNr', # Buyer\
    'dealNr', # Deal\
    'bidderNr', # DSP\
    'size', # Crative Size\
    'paymentTypeId', # Payment type\
    'mediaTypeId', # Media type\
    'dealTypeId', # Deal type\
    'orderNr', # Order\
    'lineItemNr', # Line item\
```

This corresponds to the dimensions in the standard GUI reporting.
{% endstep %}

{% step %}

## Selecting the metrics you wish to report on:

Anything that can be reported on in Yield UI, can be exported via the API Pull.

```python
sums = [\
    'revenue', # API Gross revenue\
    'revenueAfterSsp', # Total revenue\
    'soldImpressions', # Sold impressions\
    'clicks', # Clicks\
    'ism',     # Viewable Imps\
    'ismMeasured', # Viewable measured\
```

{% endstep %}

{% step %}

## Putting the settings together:

```python
reportSettings = {\
    "customCommand": "reportProgrammatic",\
  "reportFormat": "array", # new array-format..\
    "start": date,\
    "end": date,\
    # set the below to something high to include all advertisers/buyers etc without grouping them into "[Smaller advertisers]" etc.\
    "maxAdvertisers": '10000000',\
    "attributes": {\
        "advertiserNr": {\
            "externalId": True,\
        },\
        "dealNr": {\
            "dealId": True,\
            "name": True,\
        },\
        "sourceId": {\
            "id": True,\
            "name": True,\
        }\
    },\
    "groupBy": groupBy,\
    "sums": sums,\
    # uncomment the 'advMappingId'-row to not use the default advertiser mappings, that would be the same as using this report UI-setting:\
    # Other options => Advertiser mapping => [Ignore default mappings]\
​
    # "advMappingId": "no_mapping_magic",\
```

This is where you compile the options listed above into a coherent report.

* **maxAdvertisers:** Use this to limit the number of advertisers if there is a very large number.
* **attributes:** Additional information that can be included if needed.
* **advMapping:** Determines whether to apply the advertiser mappings used in the GUI.
  {% 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/readme.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.
