Last updated

Reporting API V2

Documentation WIP

We are actively working on improving these docs. Please reach out if you have any comments or suggestions.

Concepts

This is the new Reporting API. It's designed to be more flexible and easier to work with programmatically.

A few differences with our V1 API:

  • All responses are in JSON instead of CSV. This allows for more flexibility and better error handling.
  • There are now 2 types of responses: Paginated and Streaming. The latter is more efficient for large results.
  • Authentication is only done via JWT tokens. Cookie adama_session is no longer supported.
  • The HTTP method to perform requests is now POST instead of GET.
  • fields is used for both dimensions and metrics.

Dataset

This was known as a Report in the previous version of the API.

A dataset is a collection of dimensions and metrics that can be queried.

Beta datasets

Datasets marked as (beta) are subject to change or removal without prior notice, and are offered as is with no support.

Date fields

All datetime fields will be in RFC3339 format. For example: 2023-07-27T12:00:00Z.

Requests must use this format for start_time and end_time.

When using a rollup other than all, a field agg_timestamp will be included in the response and it will also be available for ordering. This field will have truncated datetime values based on the rollup value.

Time Windows

Time windows are used to specify a relative period of time to query. The possible values are:

  • current_date: Today
  • yesterday: Yesterday
  • last_N_hours: Last N hours (e.g. last_12_hours) up to but not including the current hour.
  • last_N_days: Last N days (e.g. last_7_days) up to but not including today.
  • campaign_to_date: From the campaign start date to today.
  • flight_to_date: From the flight start date to today.

Not all datasets support all time windows.

Rollups

Rollups are used to aggregate data at different levels. The possible values are:

  • all: No rollup
  • by_hour: Rollup by hour
  • by_day: Rollup by day
  • by_week: Rollup by week, truncated to the first day of the week
  • by_month: Rollup by month, truncated to the first day of the month

Requests

The base URL for the API is https://api.mediamath.com/reporting/v2. Each dataset has its own endpoint, for example: https://api.mediamath.com/reporting/v2/performance.

All requests must be made using the POST method. The body of the request must be a JSON object with the following schema:

{
  // Array of fields to include in the response
  "fields": [
    "string",
    "..."
  ],
  // Filters to apply to the query
  "filters": [
    {
      "field": "filter1",
      "value": 1
    }
  ],
  // Order to apply to the results
  "order": [
    {
      // Descending order
      "desc": false,
      "field": "agg_timestamp"
    }
  ],
  // Pagination is optional and not all datasets support it
  "pagination": {
    "page_size": 100,
    "page_index": 0
  },
  "rollup": "by_hour",
  "time_window": "last_7_days",
  "start_time": "2023-07-27T00:00:00Z",
  // end_time is optional
  "end_time": "2023-07-28T12:00:00Z"
}

time_window and start_time are required but mutually exclusive. If both are present, time_window will be used.

Filter

A filter is an object with 4 fields:

  • field: The field to filter by
  • value: The value to filter by. Ignored if op is and or or.
  • op: The operator to use for the filter. Defaults to =. Possible values:
    • =: Equals or contains if value is an array
    • !=: Not equals
    • >: Greater than
    • >=: Greater than or equals
    • <: Less than
    • <=: Less than or equals
    • =~: Text contains (case-insensitive)
    • and: All filters must match
    • or: At least one filter must match
  • filters: An array of filters. Required if op is and or or.
{
  "field": "dimension1",
  "op": "=~",
  "value": "Test Campaign"
}

Complex filters

When using and or or operators, the filters field must be present. Nesting filters is supported.

{
  "field": "dimension1",
  "op": "and",
  "filters": [
    {
      "field": "dimension2",
      "op": ">=",
      "value": 100000
    },
    {
      "field": "dimension3",
      "op": "<",
      "value": 110000
    }
  ]
}

Responses

All examples in these docs are formatted and may include comments. The actual responses won't have indentation and will always include a JSON object per line. This is an important clarification because the same type of error message is used for both Paginated and Streaming responses.

Error responses

When an error occurs, the response will include an error code, a request ID, and a message.

When reaching out to support, please include the complete response.

{
  "error_code": "BadRequest",
  "request_id": "74K33s47Yd1ns97E9RZsfFhn1Gj0ehYs",
  "message": "field does not exist in this dataset: campaign_id_test"
}

Paginated response

Paginated responses will include a meta object with pagination information and a results array with the actual data. To use pagination, the request must include a pagination object with page_size and page_index.

  • page_size: The number of records to return per page. The minimum value is 1 and the maximum value is 1000.
  • page_index: The index of the page to return. The first page is 0.
{
  // ...
  "pagination": {
    "page_size": 100,
    "page_index": 0
  },
  // ...
}

Streaming response

The response consists of a header followed by the result-set. In case of failure, a special error message will be returned and the stream will finish. Also, at any time there can be a Metadata message with additional information.

The client is responsible for any validation checks such as checking that total_items_count matches the number of records returned.

{
  "fields": [
    {
      "name": "agg_timestamp"
    },
    {
      "name": "campaign_id"
    },
    {
      "name": "impressions"
    }
  ],
  // An integer or -1 if the total number of records couldn't be calculated
  "total_items_count": 14
}

Data

{
  "field1": "value1",
  "field2": 2,
  "agg_timestamp": "2023-07-27T12:00:00Z"
}

Error

A regular error message will be returned in case of failure. The stream will finish after this message.

Metadata

Information such as progress, warnings, or other details that are not part of the result-set.
At the moment there aren't any metadata messages.

{
  "meta": {}
}

Examples

Paginated response

Request

{
  "fields": [
    "campaign_id",
    "impressions"
  ],
  "filters": [
    {
      "field": "organization_id",
      "op": "=",
      "value": 123456
    },
    {
      "field": "advertiser_id",
      "value": 123456
    },
    {
      "field": "campaign_name",
      "op": "=~",
      "value": "Test Campaign"
    }
  ],
  "order": [
    {
      "desc": false,
      "field": "agg_timestamp",
      "nulls_last": true
    }
  ],
  "pagination": {
    "page_size": 100,
    "page_index": 0
  },
  "rollup": "by_hour",
  "time_window": "last_7_days"
}

Response

{
  "meta": {
    "page_index": 0,
    "total_pages": 1,
    "items_count": 3,
    "total_items_count": 3,
    "status": "OK"
  },
  "results": [
    {
      "campaign_id": 1,
      "impressions": 93283,
      "agg_timestamp": "2023-07-27T12:00:00Z"
    },
    {
      "campaign_id": 2,
      "impressions": 474,
      "agg_timestamp": "2023-07-27T12:00:00Z"
    },
    {
      "campaign_id": 3,
      "impressions": 45775,
      "agg_timestamp": "2023-07-27T12:00:00Z"
    }
  ]
}

Streaming response

Request

{
  "fields": [
    "campaign_id",
    "impressions"
  ],
  "filters": [
    {
      "field": "organization_id",
      "op": "=",
      "value": 123456
    },
    {
      "field": "advertiser_id",
      "value": 123456
    },
    {
      "field": "campaign_name",
      "op": "=~",
      "value": "Test Campaign"
    }
  ],
  "order": [
    {
      "desc": false,
      "field": "agg_timestamp",
      "nulls_last": true
    }
  ],
  "rollup": "by_hour",
  "time_window": "last_7_days"
}

Successful response

This is formatted for readability but the real response will be a single line per object.

{
  "fields": [
    {
      "name": "agg_timestamp"
    },
    {
      "name": "campaign_id"
    },
    {
      "name": "impressions"
    }
  ],
  "total_items_count": 14
}
{
  "campaign_id": 1,
  "impressions": 93283,
  "agg_timestamp": "2023-07-27T12:00:00Z"
}
{
  "campaign_id": 2,
  "impressions": 474,
  "agg_timestamp": "2023-07-27T12:00:00Z"
}
{
  "meta": {}
}
{
  "campaign_id": 3,
  "impressions": 45775,
  "agg_timestamp": "2023-07-27T12:00:00Z"
}

cURL

curl --location 'https://api.mediamath.com/reporting/v2/performance' \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer $JWT_TOKEN" \
--data '{
  "fields": [
    "campaign_id",
    "impressions"
  ],
  "filters": [
    {
      "field": "organization_id",
      "op": "=",
      "value": 123456
    },
    {
      "field": "advertiser_id",
      "value": 123456
    },
    {
      "field": "campaign_name",
      "op": "=~",
      "value": "Test Campaign"
    }
  ],
  "order": [
    {
      "desc": false,
      "field": "agg_timestamp",
      "nulls_last": true
    }
  ],
  "rollup": "by_day",
  "time_window": "last_7_days"
}'