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 ofGET
. fields
is used for bothdimensions
andmetrics
.
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
andend_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
: Todayyesterday
: Yesterdaylast_N_hours
: LastN
hours (e.g.last_12_hours
) up to but not including the current hour.last_N_days
: LastN
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 rollupby_hour
: Rollup by hourby_day
: Rollup by dayby_week
: Rollup by week, truncated to the first day of the weekby_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 byvalue
: The value to filter by. Ignored ifop
isand
oror
.op
: The operator to use for the filter. Defaults to=
. Possible values:=
: Equals or contains ifvalue
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 matchor
: At least one filter must match
filters
: An array of filters. Required ifop
isand
oror
.
{
"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 is1
and the maximum value is1000
.page_index
: The index of the page to return. The first page is0
.
{
// ...
"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.
Header
{
"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"
}'