DSP Reporting API

Modified on Wed, 4 Nov at 6:18 AM

bideaseAPI REFERENCE
Reporting API
Retrieve performance and spend data in CSV format with a single GET request.
⇨
GET + query string
Every request is a GET with parameters in the query string; the response is a CSV file.
⚿
API token
Pass api-token in every request. Get it from your Bidease account manager.
◷
Token timezone
All dates and times are in the token timezone, UTC+0 by default.
REFERENCE
Building a Request
1
Request URL

All requests use the GET method with query strings.

REQUEST URL EXAMPLE
https://ui-api.bidease.com/api/reporting/v1/stats?api-token={API_TOKEN}&fromdate={FROM_DATE}&todate={TO_DATE}&rekls={REKL}&products={PRODUCT}&campaigns={CAMPAIGN}&group={GROUP1}&group={GROUP2}
ParameterDescription
api-tokenMandatory in each request. Provided by your Bidease account manager.
fromdateStart date (inclusive), formatted as YYYY-MM-DD.
todateEnd date (exclusive), also in YYYY-MM-DD format.
noheaderAdd &noheader=true to exclude the CSV header.
2
Dates
⚠️
TO_DATE must be greater than FROM_DATE. Both dates should be within the range (today − 1 year; today); the total amount of data retrieved can vary and affect the start date.

FROM_DATE and TO_DATE also support relative dates matching this regular expression:

RELATIVE DATE
^today(-\d+d)?$

The API call uses the date in the API token's timezone, and today refers to the start of the day when the call is made:

■
today — YYYY-MM-DD
■
today-20d — today minus 20 days
EXAMPLE: YESTERDAY
&fromdate=today-1d&todate=today
ⓘ
Timezone: all dates and times are in the token timezone (UTC+0 by default).
3
Grouping

You can group data by up to 9 values with repeated group parameters:

ValueDescription
ApplicationBundle of the application where the impression was served
CarrierCarrier of the connection
CityCity
CountryCountry (ISO-3)
DayDay of the event
ExchangeExchange name
HourHour of the event (in the API token timezone)
ModelMobile phone model
RegionRegion or subarea
MakeMobile phone make
CreativeHashUnique value of creative resources
DeviceTypeType of device (Mobile, Tablet)
OperationSystemOperating system
CampaignIDID of the campaign
CampaignNameName of the campaign
CreativeIDID of the creative
OperationSystemVersionOperating system version
PlacementIDIn-app placement ID (e.g. one bundle can have different ad placements: 320x50 at the bottom and an interstitial)
HasIFAWhether the device advertising identifier was passed
AdvertiserIDID of the advertiser on ui.bidease.com
ProductIDID of the product on ui.bidease.com
AdBundleBundle of the advertised app (product)
AdvertiserProductNameAdvertiser and product name, as Advertiser / Product
ReklIDID of the advertiser (same as AdvertiserID)
ReklNameName of the advertiser
CurrencyCurrency of the payment during a payment event
ConvHourHour of the conversion (install)
ImpressionHourHour of the impression
ConvDayDay of the conversion (install)
ImpressionDayDay of the impression
ResourcesThe combination of resources the creative used in the ad impression. Each row is one combination, not one resource. Recommended: group=resources.name — returns a comma-separated list of resource IDs.
MainResourceThe main resource the creative used in the ad impression. Recommended: group=mainresource.resource_id — returns the resource ID.
GROUPING EXAMPLES
https://ui-api.bidease.com/api/reporting/v1/stats?api-token={API_TOKEN}&fromdate={FROM_DATE}&todate={TO_DATE}&group=Day&group=CampaignID&group=CampaignName

https://ui-api.bidease.com/api/reporting/v1/stats?api-token={API_TOKEN}&fromdate={FROM_DATE}&todate={TO_DATE}&group=CreativeID&group=HasIFA&group=PlacementID
ⓘ
Custom bindings: if the Bidease AdOps team uses custom bindings on your campaigns, you can retrieve them as a separate grouping with the group-by-param parameter, e.g. &group-by-param=CustomCampaign.
4
Filters

Filter data with these parameters; each accepts zero or more values:

ParameterDescription
reklsAdvertiser IDs from the Bidease UI
productsProduct IDs from the Bidease UI
campaignsCampaign IDs from the Bidease UI
bundlesApp bundles from Google Play and the App Store
EXAMPLE
&campaigns=10&campaigns=11&bundles=com.bidease&bundles=1133415133&rekls=304&rekls=404
⚠️
No filters = all data. If no filters are provided, all available data is analyzed.
5
Time attribution

There are three types of time attribution:

TypeTimestamp used
EventWhen an action (impression, click, conversion, purchase) was recorded
ImpressionWhen the impression occurred
ConversionWhen the conversion occurred

Accordingly, there are three day groupings:

GroupingDescription
DayDay of the event (YYYY-MM-DD)
ImpressionDayDay of the impression (YYYY-MM-DD)
ConvDayDay of the conversion, applied to the conversion and all related events, including events before it such as the impression or click (YYYY-MM-DD)

Select the attribution with the attr-type parameter:

attr-typeGroups by
ByEventEvent timestamp (default)
ByImpressionImpression timestamp
ByConvConversion timestamp
EXAMPLE
&group=ImpressionDay&attr-type=ByImpression
6
Extra columns

Add more columns to the CSV with repeated extra-column parameters. Available values can be found in the Bidease UI.

EXAMPLE
&extra-column=UniqClicks&extra-column=Ecpa4&extra-column=UniqImpressions
7
Sample request

Data for advertisers 300 and 310, grouped by application, country, creative ID and campaign ID, for December 2019:

SAMPLE REQUEST
https://ui-api.bidease.com/api/reporting/v1/stats?api-token=XXX-XXX-XXXX-XXX-XXXX&fromdate=2019-12-01&todate=2020-01-01&rekls=300&rekls=310&group=Application&group=Country&group=CreativeID&group=CampaignID
8
Response format

The resulting CSV includes columns such as:

ColumnDescription
spendMedia cost in dollars
impressionsNumber of impressions
clicksNumber of clicks
conversionsNumber of installs
revenueValue passed from MMPs; required for agencies to calculate their revenue
iap_sumSum of in-app purchases
iapNumber of in-app purchases
goal1–goal6Number of in-app events, as configured in the Bidease UI
ctrClick-through rate
ecpmEffective cost per thousand impressions
ecpcEffective cost per click
cpiCost per install
ⓘ
Column order: after the metric columns come the grouping columns, in the same order as in your request.

To get only the metric columns you need, list them with repeated field parameters. The rest of the metrics are then left out of the CSV; the grouping columns are still included.

EXAMPLE
&field=spend&field=impressions&field=clicks
9
Google Sheets integration

You can use the Bidease Reporting API directly in Google Sheets with Google Apps Script. The example script below goes into a spreadsheet-bound Apps Script project: it requests the previous day's data and appends the results to the specified sheet.

■
Specify your Bidease API token in the CONFIG constant (apiToken field)
■
Specify the sheet where API results will be appended (sheetName field)
■
Configure the required groupings, filters and extra columns as described above
■
Create a daily time-driven trigger in Apps Script (recommended time: 01:00 UTC)
APPS SCRIPT
// Main Config
// Specify your Bidease API token in apiToken parameter.
// Specify name of spreadsheet which will be used as sheet for getting API results. 

const CONFIG = {
  apiToken: "YOUR-API-TOKEN",
  sheetName: "Sheet1",
  baseUrl: "https://ui-api.bidease.com/api/reporting/v1/stats",

// GROUPINGS
// Put any groupings supported by Bidease API here.
  groups: [
    "Day",
    "CampaignID"
  ],

// FILTERS
// Put any filters supported by Bidease API here.
  filters: {
    //rekls: [123, 1234],
    //campaigns: [111, 222],
  },

// EXTRA COLUMNS
// Put any extra columns supported by Bidease API here.
  extras: {
    //"extra-column": ["Ecpa4", "Ecpa3"]
  }
};

function run() {
  console.log("run(): START");

  try {
    const { url } = _buildBideaseUrl_();

    console.log("===== Bidease API REQUEST =====");
    console.log("Method: GET");
    console.log("URL: " + url);
    console.log("================================");

    const response = UrlFetchApp.fetch(url, {
      method: "GET",
      muteHttpExceptions: true,
    });

    const status = response.getResponseCode();
    console.log("Response status: " + status);

    if (status !== 200) {
      console.log("Response body (non-200): " + response.getContentText());
      return;
    }

    const csvText = response.getContentText();
    if (!csvText) {
      console.log("Empty API response");
      return;
    }

    const csvData = Utilities.parseCsv(csvText);
    console.log(`CSV rows received: ${csvData.length}`);

    _appendToSheet_(csvData);
  } catch (e) {
    console.log("Execution error: " + (e && e.stack ? e.stack : e));
  } finally {
    console.log("run(): END");
  }
}

function _getDateParams_() {
  const now = new Date();

  const todayUTC = new Date(Date.UTC(
    now.getUTCFullYear(),
    now.getUTCMonth(),
    now.getUTCDate()
  ));

  const yesterdayUTC = new Date(todayUTC);
  yesterdayUTC.setUTCDate(todayUTC.getUTCDate() - 1);

  const format = (d) => Utilities.formatDate(d, "UTC", "yyyy-MM-dd");

  return {
    fromdate: format(yesterdayUTC),
    todate: format(todayUTC),
  };
}

function _buildBideaseUrl_() {
  const dates = _getDateParams_();

  const params = {
    "api-token": CONFIG.apiToken,
    fromdate: dates.fromdate,
    todate: dates.todate,
  };

  const pairs = [];

  _pushParamPairs_(pairs, params);

  (CONFIG.groups || []).forEach((g) => pairs.push(["group", g]));

  _pushParamPairs_(pairs, CONFIG.filters || {});

  _pushParamPairs_(pairs, CONFIG.extras || {});

  const query = pairs
    .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
    .join("&");

  return { url: `${CONFIG.baseUrl}?${query}` };
}

function _pushParamPairs_(targetPairs, obj) {
  Object.keys(obj || {}).forEach((key) => {
    const value = obj[key];

    if (value === null || value === undefined) return;

    if (Array.isArray(value)) {
      value.forEach((item) => {
        if (item === null || item === undefined || item === "") return;
        targetPairs.push([key, item]);
      });
      return;
    }

    if (value === "") return;

    targetPairs.push([key, value]);
  });
}

function _appendToSheet_(csvData) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  if (!ss) throw new Error("Active spreadsheet not found");

  const sheet = ss.getSheetByName(CONFIG.sheetName);
  if (!sheet) throw new Error(`Sheet "${CONFIG.sheetName}" not found`);

  const lastRow = sheet.getLastRow();

  let rowsToAppend;
  if (lastRow === 0) {
    console.log("Sheet is empty → writing header and data");
    rowsToAppend = csvData;
  } else {
    console.log("Sheet not empty → skipping CSV header");
    rowsToAppend = csvData.slice(1);
  }

  if (!rowsToAppend.length) {
    console.log("No data rows to append");
    return;
  }

  sheet
    .getRange(lastRow + 1, 1, rowsToAppend.length, rowsToAppend[0].length)
    .setValues(rowsToAppend);

  console.log(`Appended ${rowsToAppend.length} rows`);
}
bidease
Grow Your App with Ease
Questions? Contact your Bidease account manager
support@bidease.com

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article