# DT Exchange Reporting API

The DT Exchange Reporting API enables you to access all the reporting data from the monetization ad units. You can query multiple metrics, such as revenue and impressions, across the available dimensions and even implement filters.

## Reporting API Workflow <a href="#section-reporting-api-workflow" id="section-reporting-api-workflow"></a>

The publisher makes a POST request using the Client ID and Client Secret to receive the Access Token, as described in [Step 1](#h_01gkp00mcq3d07d53wc3608hfg).

Once the request is successful, and the Access Token is received, an API Request is made to create a custom report as described in [Step 2](#section-step-2-reporting-api-request). A successful response will contain a URL leading to a file that will be populated with the custom report. More details can be found in [Step 3](#section-step-3-receiving-the-custom-report).

## Step 1: Obtaining the Access Token <a href="#h_01gkp00mcq3d07d53wc3608hfg" id="h_01gkp00mcq3d07d53wc3608hfg"></a>

DTs Reporting API uses Access Tokens for authentication purposes. To obtain your Access Token, you must first get your Client ID and Client Secret.

The base End Point for the entire process is: `https://reporting.fyber.com`

#### Authentication Token <a href="#h_01gkp01247yz7swwfhjxtnwwg3" id="h_01gkp01247yz7swwfhjxtnwwg3"></a>

```
POST /auth/v1/token
```

#### Headers <a href="#h_01hrsm6vapbyc9stbyxfte019c" id="h_01hrsm6vapbyc9stbyxfte019c"></a>

```
Content-Type    application/json
```

#### Sample Request <a href="#h_01hrsm6vapfmygqzyvd1591qd3" id="h_01hrsm6vapfmygqzyvd1591qd3"></a>

```html
https://reporting.fyber.com/auth/v1/token
```

#### Params <a href="#h_01hrsm6vapjh0jfhkmd2htp1db" id="h_01hrsm6vapjh0jfhkmd2htp1db"></a>

```
format  csv
```

#### Body: raw (application/json) <a href="#h_01hrsm6vaq432b3mr2b5dtt8n8" id="h_01hrsm6vaq432b3mr2b5dtt8n8"></a>

{% code title="JSON" %}

```json
{
    "grant_type": "client_credentials",
    "client_id": "3ce66d885XXXXXXXXXXa3b752bb9058",
    "client_secret": "YtMvC7VYTQMQ7w9UCUaFXXXJnwVZnQqqN02XNyt8IIh2h8XFDuXXXXXXXXSS6XTrFWW4TkebCcMLJkrXSw5IurkearTJIDzUxsbiMXv8hb4T23MwN6eE7DDIthRFqDnhnuhiDlY2oPeaOjsMbzE8joZ5cs6tsySJz6uZXwJ-x3lcYaYbgXXXXXXXX3_hFeuXm-C7-me2V1MMs-ftJxTd5QbHoUhG3Q5anCWCW_pg8x3CL4yPGCbpWUDZfpdNPyyCT4rxCEb-VC0Bdqwe8N2GGn_VSFOwQYxa-yap2JuNSGJfl_ZURXXXXXXXXFe1GpHDn8pk7yYwQYIGAg"
}
```

{% endcode %}

{% hint style="info" %}
Note the following:

* **Grant Type** must be `client_credentials`.
* The credentials are sent according to the OAuth 2.0 protocol.
  {% endhint %}

### Sample Authentication Response <a href="#h_01hrsm6vaqmf70nkym897agmhb" id="h_01hrsm6vaqmf70nkym897agmhb"></a>

When an authentication request is successful, you receive the following response in JSON format:

#### Successful Response <a href="#h_01hrsm6vaq0jjfaaw90871hh3c" id="h_01hrsm6vaq0jjfaaw90871hh3c"></a>

{% code title="JSON" overflow="wrap" %}

```json
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXXXJ9.eyJpYXQiOjE1NzAwMTY5MDAsImV4cCI6MTU3MDAyMDUwMCwiYXVkIjoic3BlZWRiYWxsIiwic3ViIjoiMjEwMjYzIn0.hDo1waTytSys_oRhFNUPqZPom26bL05rxgtSt3XYHqI",
  "tokenType": "bearer",
  "expiresIn": 3600
}
```

{% endcode %}

**accessToken**: The token required to continue the process\
**tokenType**: Bearer\
**expiresIn**: 3600 seconds (1 hour)

| Parameter     | Description                                |
| ------------- | ------------------------------------------ |
| `accessToken` | The token required to continue the process |
| `tokenType`   | Bearer                                     |
| `expiresIn`   | 3600 seconds (1 hour)                      |

#### Unsuccessful Response

When a request is unsuccessful, you receive the following response:

{% code title="JSON" overflow="wrap" %}

```json
{
  "error": "internal_server_error"
} 
```

{% endcode %}

### Possible Authentication Errors <a href="#section-possible-authentication-errors" id="section-possible-authentication-errors"></a>

Set out in the table is a list of possible errors which resulted in an unsuccessful response.

| HTTP Status Code | Error                    | Scenario                                                                                                                                                               |
| ---------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`            | `unsupported_grant_type` | N/A                                                                                                                                                                    |
| `400`            | `invalid_request`        | When there are missing credentials                                                                                                                                     |
| `400`            | `invalid_client`         | <p>When the credentials are incorrect or cannot be recognized.<br>Can also occur when your account has been disabled or when the credentials<br>have been revoked.</p> |
| `500`            | `internal_server_error`  | Unexpected errors in DT's servers                                                                                                                                      |

## Step 2: Reporting API Request <a href="#section-step-2-reporting-api-request" id="section-step-2-reporting-api-request"></a>

Use the access token you received in [Step 1](#h_01gkp00mcq3d07d53wc3608hfg) to request your custom report.

The request is made up of five individual sections:

* Source
* Date Range
* Metrics
* Splits
* Filters (include)

### Request Example <a href="#h_01hrsm6vaqnf6kjctevp2j2285" id="h_01hrsm6vaqnf6kjctevp2j2285"></a>

Set out below is a request example&#x20;

**Source**

Below is an example from the Demand Performance report. Therefore, the source is "mediation".

* The Source must be in lowercase.

**Date Range**

Start date: 2019-01-06\
End date: 2019-09-25

**Metrics**

* Bid Requests
* Bid Responses
* Impressions
* Clicks
* Rewarded Completions
* Revenue (USD)

**Splits (dimensions)**

* Fyber App ID

**Filters**

* Dimension filtered is the country
* Values filtered are US, CA and RU

For further descriptions about the terms used in this article, see [Using the Reports](https://app.gitbook.com/s/LbREhkP3WlLtP6TNVZ2Q/reports/using-the-reports).

#### URL <a href="#h_01hrsm6vaqv1r33fqjfgnht9rs" id="h_01hrsm6vaqv1r33fqjfgnht9rs"></a>

```json
https://reporting.fyber.com/api/v1/report?format=csv
```

#### Headers <a href="#h_01hrsm6vaq9mste8njacpjgr48" id="h_01hrsm6vaq9mste8njacpjgr48"></a>

```json
Content-Type:   application/json
Authorization: Bearer <Access Token from Authentication Response>
```

#### Params <a href="#h_01hrsm6vaqmpf8kd8xntq8597q" id="h_01hrsm6vaqmpf8kd8xntq8597q"></a>

```json
format  csv
```

#### Body. raw (application/json) <a href="#h_01hrsm6vaqp8nax5036wsk3wf6" id="h_01hrsm6vaqp8nax5036wsk3wf6"></a>

{% code title="JSON" %}

```json
{
    "source": "mediation",
    "dateRange": {
        "start": "2019-07-01",
        "end": "2019-09-25"
    },
    "metrics": [
        "Bid Requests",
        "Bid Responses",
        "Impressions",
        "Clicks",
        "Rewarded Completions",
        "Revenue (USD)"
    ],
    "splits": [
        "Fyber App ID"
    ],
    "filters": [
        {
            "dimension": "Country",
            "values": [
              "US",
              "CA",
              "RU"
            ]
        }
    ]
}
```

{% endcode %}

If no `splits` or `filters` are required, their value should be an empty array. However, `source`, `dateRange`, and `metrics` must include a value.

For example:

{% code title="JSON" %}

```json
{
    "source": "mediation",
    "dateRange": {
        "start": "2019-06-01",
        "end": "2019-09-25"
    },
    "metrics": [
        "Bid Requests"
    ],
    "splits": [],
    "filters": []
} 
```

{% endcode %}

### Responses <a href="#h_01hrsm6vaq8ngcrkpwfcmp74ct" id="h_01hrsm6vaq8ngcrkpwfcmp74ct"></a>

Set out below are examples of both successful and unsuccessful responses.

#### Successful Response

{% code title="JSON" %}

```json
{
  "id": "6fad42cb-25db-4af0-8988-1e7d8e6d90bc",
  "url": "https://fyber-async-reports.s3.amazonaws.com/group%3D210263/6fad42cb-25db-4af0-8988-1e7d8e6d90bc.csv?AWSAccessKeyId=AKIAQBQNZ5FY23OTK4UD&Expires=1570020564&Signature=LbhE5uljlPEKQRTbepDqmDgJuFQ%3D",
}
```

{% endcode %}

* The `id` field holds an identifier of the request for later troubleshooting, if required.
* The `url` field holds the URL to be polled (GET request) until the body response (file) is populated.

#### Unsuccessful Response <a href="#h_01hrsm6vaqdxbxa81xxnmkaamv" id="h_01hrsm6vaqdxbxa81xxnmkaamv"></a>

{% code title="JSON" %}

```json
{
  "error": "invalid_token"
}
```

{% endcode %}

#### Possible Errors <a href="#h_01hrsm6vaq57kjpv4wqh2y2r92" id="h_01hrsm6vaq57kjpv4wqh2y2r92"></a>

The table below shows the main errors indicating an unsuccessful response.

| HTTP Status Code | Error                   | Description (optional)                                                                                                                                                                                                                                                     | Scenario                                                                                                                                                                |
| ---------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 401              | invalid\_token          | N/A                                                                                                                                                                                                                                                                        | <p><em>Authorization header is empty</em><br>Authorization header not sent or token is not present in the header<br><em>Unrecognized token</em><br>Disabled account</p> |
| 400              | invalid\_format         | N/A                                                                                                                                                                                                                                                                        | Format is not supported - currently only csv format is supported                                                                                                        |
| 400              | invalid\_query          | <p>For example:<br>Invalid value undefined supplied to : Query/dateRange: DateRange<br><br>-or-<br><br>Invalid value "XXXXX" supplied to : Query/dateRange: DateRange/end: Date<br><br>-or-<br><br>Invalid dimensions: A,B,C<br><br>-or-<br><br>Invalid metrics: A,B,C</p> | <p><em>If the query sent is not in the expected schema</em><br>Date range is not sent in the ISO 8601 format<br><em>Invalid dimensions</em><br>Invalid metrics</p>      |
| 400              | invalid\_source         | Invalid source: XXXXX                                                                                                                                                                                                                                                      | Unsupported source type                                                                                                                                                 |
| 500              | internal\_server\_error | N/A                                                                                                                                                                                                                                                                        | Error in DT's servers                                                                                                                                                   |

## Step 3: Receiving the Custom Report <a href="#section-step-3-receiving-the-custom-report" id="section-step-3-receiving-the-custom-report"></a>

To obtain the Custom Report, follow the steps below:

1. Receive the URL from the successful response in [Step 2](#section-step-2-reporting-api-request).
2. Perform polling on the URL to access the file containing the custom report. The empty file is populated within one hour, depending on the size of the query.
3. If the file is not populated with data after one hour, resend the request.

The URL is valid for three hours.

## Additional Information and Restrictions <a href="#h_01hrsm6vaqp4tdnpwz9fbc5b76" id="h_01hrsm6vaqp4tdnpwz9fbc5b76"></a>

It is important to take note of all the information, restrictions and rules to ensure a successful response.&#x20;

### General <a href="#h_01hrsm6vaqq7gbefk1bsffhk6f" id="h_01hrsm6vaqq7gbefk1bsffhk6f"></a>

* All reports are presented in US dollars
* The time zone used is UTC
* Data related to mediated networks is re-aggregated twice a day and updated for two weeks retroactively
* The Reporting APIs are available on a daily level, with a delay of up to 12 hours from the end of day UTC&#x20;

### Query Restrictions <a href="#h_01hrsm6vaqn674j840wv7z6k8z" id="h_01hrsm6vaqn674j840wv7z6k8z"></a>

* All fields are mandatory. Splits and Filters can have an empty array. See example in [Step 2](#section-step-2-reporting-api-request).
* The time range for a report query is limited to 90 days
* Queries are limited to a maximum of 50 per day, per API
* You can query each one of the defined dimensions in the Reporting API calls by up to 7 dimensions in a single query
* You are restricted to 5 filters per query
* To receive a breakdown by date, it must exist in the "splits" array

### Date Range Restrictions <a href="#h_01hrsm6vaqbta3g7924b53j314" id="h_01hrsm6vaqbta3g7924b53j314"></a>

There are a number of rules that must be observed with regard to the date range:

* The start date and end date must be in the format of ISO 8601. For example, 2019-10-03
* The interval between the start and end date should not exceed 90 days
* The start date must be earlier or equal to the end date
* The start date must be no later than the previous 18 months
* The end date cannot be the current day's date or beyond it
* The start date and end date are included in the report

{% hint style="info" %}
Data for Mediation is available from 2022-11-07 onwards

Queries with the current day's date or dates prior to the above time periods result in an HTTP 400 status code (invalid\_query)
{% endhint %}

## Supported Metrics and Dimensions <a href="#h_01gkp0e0wnqf630fvgy12hdkrm" id="h_01gkp0e0wnqf630fvgy12hdkrm"></a>

You must specify in the API Request the source, metrics, dimensions, and optional filters you want to include in your custom report.

### Metrics <a href="#h_01hrsm6vaqyes2vm2cdkhpd0dg" id="h_01hrsm6vaqyes2vm2cdkhpd0dg"></a>

The following source mediation metrics are supported:&#x20;

* Bid RequestsBid Responses
* Impressions
* Clicks
* Rewarded Completions
* Revenue (USD)
* Ad Requests

### Dimensions <a href="#h_01hrsm6vaqtemqeb9vb8fxxr1r" id="h_01hrsm6vaqtemqeb9vb8fxxr1r"></a>

The following source mediation dimensions are supported:&#x20;

* Date
* App Name
* App Bundle
* Fyber App ID
* Placement ID
* Placement Name
* Placement Type: (Available values: Banner, Interstitial, Rewarded)
* Country
* Device OS: (Available values: iOS, Android)
* Demand Source Type Name: (Available values: Programmatic, Custom API)
* Demand Source Name
* Publisher ID

### Filters <a href="#h_01hrsm6vaqade6ygznpsp81xsh" id="h_01hrsm6vaqade6ygznpsp81xsh"></a>

You can set an include filter on any value(s) within a dimension. This means that all the data presented in the report relates only to the values defined in the filter.

For example:\
**Dimension** = Country\
**Filtered Value** = US or CA

As a result of these filters, the report will contain data relevant only for the countries US and CA.
