Skip to main content

Reporting API Documentation

This documentation provides details on how to use the Reporting API to generate reports for the OCM Dashboard.

Base URL

https://app.orangeclickmedia.com/api/v1

Authentication

The API uses token-based authentication. To access protected routes, you must include a Bearer token in your request headers.

To obtain a Bearer token, please contact us at [email protected] and ask for API token generation permissions.

Header Example:

Authorization: Bearer YOUR_API_TOKEN
Accept: application/json
Content-Type: application/json

Rate Limiting

To ensure stability, the reporting API is rate-limited to:

  • 5 requests per minute per user.

If you exceed this limit, the API will return a 429 Too Many Requests status code. The response will also include a Retry-After header indicating the number of seconds to wait before making another request.

Example 429 Response Header:

HTTP/1.1 429 Too Many Requests
Retry-After: 45

Generate Report

Generates a report based on the provided dimensions, metrics, and grouped filters.

  • Endpoint: POST /reports/generate
  • Authentication Required: Yes

Request Body Parameters

ParameterTypeRequiredDescription
dimensionsarrayYesList of dimensions to group data by (e.g., ['day', 'product']).
metricsarrayYesList of metrics to include in the report (e.g., ['impressions', 'earnings']).
currencystringYesCurrency code. Supported: EUR, USD.
selectedDatearrayNoDate range [startDate, endDate] (e.g., ["2026-01-01", "2026-01-31"]). Defaults to today if omitted. Max range: 3 months.
filter_groupsarrayNoList of filter groups to refine the results. Groups are combined with OR; filters inside each group are combined with AND. Pass an empty array or omit this field for no filters.

Dimensions

List of available dimensions:

  • day: Group by date.
  • month: Group by month.
  • year: Group by year.
  • product: Product type (Standard Display, Instream Video, etc.).
  • domain: Website domain.
  • subdomain: Website subdomain.
  • media_type: Media type (display, video, native).
  • device: Device type (desktop, mobile, tablet, etc.).
  • os: Operating system (iOS, Android, Windows, etc.).
  • ad_unit: Ad unit identifier.
  • country: Country code.
  • deal_id: Deal identifier.
  • deal_name: Deal name.
  • deal_type: Deal type (Open auction, Deal, Proposal).

Metrics

List of available metrics:

  • impressions: Number of ad impressions.
  • earnings: Net earnings.
  • ecpm: Effective Cost Per Mille.
  • viewable: Viewable impressions.
  • first_quartile: Video first quartile completes.
  • midpoint: Video midpoint completes.
  • third_quartile: Video third quartile completes.
  • complete: Video full completes.

Filters

Filters are sent as filter_groups.

Groups are combined with OR. Filters inside each group are combined with AND.

Publisher domain access and wholesaler access filters are applied automatically by the API. You do not need to include those safety filters in your request.

Each filter group must contain:

  • operator: Currently only or is supported.
  • filters: An array of one or more filter objects.

Each filter object must contain:

  • value: The dimension or metric key to filter by.
  • type: Either dimension or metric.
  • comparator: For dimensions, for example in, nin, or is_any_of.
  • selectedValues: For dimensions, a non-empty array of values.
  • comparison: For metrics, for example gte (>=), lte (<=), eq (==), or neq (!=).
  • selectedValue: For metrics, the value to compare against.
  • secondValue: For metric between comparisons, the upper value.

Request Examples

Basic Report

{
"dimensions": ["day"],
"metrics": ["impressions", "earnings"],
"currency": "EUR",
"selectedDate": ["2026-01-01", "2026-01-07"]
}

Report with Dimension Filter (Domain)

{
"dimensions": ["product"],
"metrics": ["impressions"],
"currency": "USD",
"selectedDate": ["2026-01-01", "2026-01-01"],
"filter_groups": [
{
"operator": "or",
"filters": [
{
"value": "domain",
"type": "dimension",
"comparator": "in",
"selectedValues": ["example.com", "another-domain.net"]
}
]
}
]
}

Report with Metric Filter (Impressions)

{
"dimensions": ["day"],
"metrics": ["impressions", "ecpm"],
"currency": "EUR",
"selectedDate": ["2026-01-01", "2026-01-07"],
"filter_groups": [
{
"operator": "or",
"filters": [
{
"value": "impressions",
"type": "metric",
"comparison": "gte",
"selectedValue": 1000
}
]
}
]
}

Report with OR Groups and AND Filters

{
"dimensions": ["domain", "subdomain"],
"metrics": ["impressions", "earnings", "ecpm"],
"currency": "EUR",
"selectedDate": ["2026-04-23", "2026-04-23"],
"filter_groups": [
{
"operator": "or",
"filters": [
{
"value": "domain",
"type": "dimension",
"comparator": "in",
"selectedValues": ["example.com"]
},
{
"value": "device",
"type": "dimension",
"comparator": "in",
"selectedValues": ["desktop"]
}
]
},
{
"operator": "or",
"filters": [
{
"value": "subdomain",
"type": "dimension",
"comparator": "in",
"selectedValues": ["app.example.com"]
},
{
"value": "device",
"type": "dimension",
"comparator": "in",
"selectedValues": ["desktop"]
}
]
}
]
}

This filter example means:

(domain = example.com AND device = desktop)
OR
(subdomain = app.example.com AND device = desktop)

Response Format

Success Response (200 OK)

{
"status": "success",
"data": [
{
"day": "2026-01-01",
"impressions": 50000,
"earnings": 150.25
}
],
"meta": {
"count": 1,
"start_date": "2026-01-01",
"end_date": "2026-01-01",
"currency": "EUR"
}
}

Error Response (422 Unprocessable Entity)

{
"status": "error",
"message": "Validation failed",
"errors": {
"dimensions.0": ["One or more selected dimensions are invalid."]
}
}